robotools / vanilla

A Pythonic wrapper around Cocoa.
MIT License
78 stars 28 forks source link

Radio group demo doesn't work, problem with super()? #205

Closed justinpenner closed 8 months ago

justinpenner commented 8 months ago

macOS 12.6.5 Python 3.11 Vanilla 0.5.0

I have a GlyphsApp plugin that stopped working after the Glyphs team pushed a Vanilla module update a few days ago (I think they updated from Vanilla 0.2.4 to 0.5.0).

I thought maybe something has changed in Vanilla over all those versions, but the syntax I'm using is basically the same as the example in the Vanilla docs. So I tried running the demo from https://vanilla.robotools.dev/en/latest/objects/RadioGroup.html in a fresh venv, and I get the same error that my plugin was getting:

Traceback (most recent call last):
  File "…/vanilla-test.py", line 23, in <module>
    RadioGroupDemo()
  File "…/vanilla-test.py", line 7, in __init__
    self.w.radioGroup = HorizontalRadioGroup(
                        ^^^^^^^^^^^^^^^^^^^^^
  File "…/venv/lib/python3.11/site-packages/vanilla/vanillaRadioGroup.py", line 191, in __init__
    self._init(HorizontalRadioGroup, posSize, titles, callback=callback, sizeStyle=sizeStyle)
  File "…/venv/lib/python3.11/site-packages/vanilla/vanillaRadioGroup.py", line 26, in _init
    super().__init__(posSize, spacing=spacing, alignment="leading")
TypeError: object.__init__() takes exactly one argument (the instance to initialize)

I'm a bit lost since this seems to imply that Vanilla has been broken since 0.2.4? That doesn't make sense. After some digging I found that Vanilla is using super() from pyobjc instead of Python stdlib, so maybe something is newly broken in pyobjc?

justvanrossum commented 8 months ago

FWIW: the example snippet works for me with Python 3.12 and Vanilla 0.5.

justvanrossum commented 8 months ago

Oh, and PyObjC 10.1 and 10.2: it works on both.

Check your PyObjC version, that may be the culprit.

justvanrossum commented 8 months ago
import objc
print(objc.__version__)
justinpenner commented 8 months ago

I'm still getting the same error when I try it on your setup (Python 3.12, PyObjC 10.2, Vanilla 0.5.0).

It seems like the problem is in vanillaRadioGroup.py in _RadioGroupMixin._init():

class _RadioGroupMixin(object):
…
    def _init(self, cls, posSize, titles, callback=None, sizeStyle="regular"):
…
        super().__init__(posSize, spacing=spacing, alignment="leading")

I don't fully understand the super() function, but it seems to resolve to the parent class of _RadioGroupMixin, which is Python's base object class. So why are we sending it these 3 parameters that seem to be for something else?

justinpenner commented 8 months ago

@justvanrossum Which demo did you try? The RadioGroup demo works. The problem I'm having is with HorizontalRadioGroup and VerticalRadioGroup, which are further down the doc page at https://vanilla.robotools.dev/en/latest/objects/RadioGroup.html#vanilla.HorizontalRadioGroup

justvanrossum commented 8 months ago

You're right, I ran the wrong example, can reproduce now.

typemytype commented 8 months ago

thanks Just for the fix, I was under the impression those where deprecated...

use isVertical argument in a RadioGroup

justvanrossum commented 8 months ago

I was under the impression those where deprecated...

Then maybe document them as such, and refer to the preferred way.

justinpenner commented 8 months ago

@typemytype I was under the opposite impression. In vanillaRadioGroup.py, the RadioGroup class is at the very end of the file under a commented "Legacy" heading. So I thought the correct classes to use are HorizontalRadioGroup and VerticalRadioGroup.

Thanks for the fix, Just.

typemytype commented 8 months ago

my mistake, I just followed this import https://github.com/robotools/vanilla/blob/master/Lib/vanilla/vanillaStackGroup.py#L6-L22

I guess those radio group must just use the ...StackView instead ...StackGroup