New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unify pen argument names #2919
base: main
Are you sure you want to change the base?
Unify pen argument names #2919
Conversation
Lib/fontTools/cu2qu/ufo.py
Outdated
@@ -91,7 +92,11 @@ def closePath(self): | |||
def endPath(self): | |||
self._add_segment('end') | |||
|
|||
def addComponent(self, glyphName, transformation): | |||
def addComponent( | |||
self, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mixing tabs and spaces?
feels weird we add typing only to this method and not the rest. Maybe for now just rename the parameters if you don't have time to add type hints to all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
C&P error ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've started to add typing annotations to the pens. But I had to stop now, because it gets complicated and even requires some code rewriting to pass the type checks. But at least there is more typing than before now :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, where would it require code rewriting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I needed to add some assertions, otherwise the type checker would complain about variables possibly being None, e.g.:
The tests fail ... didn’t see it locally as tox didn’t run because of lxml installation problems. I’m on it … |
Putting in a warning here, lots of things that are not fontTools pull in pens/subclass pens; please be sure that you aren't introducing breaking changes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have time to do a full review, but I notice typing_extensions
is sneaking in here as a new dependency. I don't have a strong opinion about that right now, but there was some discussion, also in the context of dropping support for Python 3.7.
|
||
|
||
PenGlyphSet: TypeAlias = Optional[Dict[str, Any]] | ||
PenPoint: TypeAlias = Tuple[float, float] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't agree that a "pen point" is a an x, y tuple. It is a sequence with length two, containing two numbers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this can be modeled in Python with anything other than tuple[float, float]
. There's an open issue for mypy with a "workaround": python/mypy#8441. The most straightfoward way still is to just call it Sequence[float]
.
Hm, I'm not sure how one can meaningfully "be sure" about it, other than to drop the PR? Maybe a GitHub search can help find some API users. |
bezierSegments.append((pt1, pt2, pt3)) | ||
pt1, pt2, pt3 = temp, None, None | ||
bezierSegments.append((pt1, points[-2], points[-1])) | ||
return bezierSegments | ||
|
||
|
||
def decomposeQuadraticSegment(points): | ||
def decomposeQuadraticSegment(points: List[Union[PenPoint, None]]) -> List[Tuple[PenPoint, PenPoint]]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can from __future__ import annotations
at the top and then rewrite this as def decomposeQuadraticSegment(points: list[PenPoint | None]) -> list[tuple[PenPoint, PenPoint]]:
:)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I wasn't sure if Python 3.7 can deal with that notation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The annotations import was added in 3.7. You still need to import the typings for type aliases though... until we have 3.10 minimum.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@anthrotype actually, I'm wondering about the points
argument, Is None
really possible? The docstring says the last point must be an on-curve point, implying that it cannot be None
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes the last point in the list (and only the last) can be None, which indicates a closed TrueType contour containing only off-curve points and no on-curves..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, but in this instance? It's only called from
fonttools/Lib/fontTools/pens/basePen.py
Line 348 in 1688400
for pt1, pt2 in decomposeQuadraticSegment(list(points)): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point you are right the caller handles that case already, if this function expects all points to be non-None that we can type it without the Optional, maybe add an assertion too
@@ -27,8 +27,8 @@ def __init__(self, glyphSet, ignoreSinglePoints=False): | |||
self.init() | |||
|
|||
def init(self): | |||
self.bounds = None | |||
self._start = None | |||
self.bounds = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happened to the indentation here?
Random thought: to avoid mixing typing and formatting changes (black?), we could first make a pens formatting PR and add the commit to a rev-ignore file as described in https://docs.github.com/en/repositories/working-with-files/using-files/viewing-a-file#ignore-commits-in-the-blame-view and set up CI to check formatting of pens from then on. |
@madig I agree that it is probably better to tackle this in separate steps. Should I prepare a new branch that only fixes the formatting for all pen code? |
Should we add deprecation messages when somebody uses the "old" argument names? The only things that actually changed are |
+1 Also we should refrain from adding typing_extension dependency until we drop support for python 3.7 (#2878) (hopefully sometime early next year once Robofont goes stable with updated python runtime) |
a client would get TypeError and it's going to be too late for issuing deprecation warning.. |
I've made a formatting-only PR in #2923. |
Ok, looked through this a bit more; these are positional arguments, so I am less concerned about breaking things, even in subclassing. I would just ask why the change of names still: baseGlyphName is used in reference to components, where that language is used for a bunch of things —so this seems to be a bit of bikeshedding, as is arguing about not changing it, so I'll drop my objections and apologize for the extra noise. |
Some pens used
baseGlyphName
andtransform
as argument names, others usedglyphName
andtransformation
. This PR unifies the argument names and adds some type annotations.