nucleic / enaml

Declarative User Interfaces for Python
http://enaml.readthedocs.io/en/latest/
Other
1.54k stars 132 forks source link

IntField handles only Int(), not Long(), fails in cryptic way #172

Closed jason-s closed 9 years ago

jason-s commented 9 years ago

I'm working with unsigned 32-bit integers, which won't fit in an int, so I need to use an atom.api.Long rather than an atom.api.Int, but then IntField won't work. But there is no LongField or LongValidator :/

This gist https://gist.github.com/jason-s/5f884e80ffd8a7c15af7 fails with TypeError: invalid instance type when I use enaml-run.

C:\mydir>enaml-run testdev/test1.enaml
Traceback (most recent call last):
  File "c:\app\python\anaconda\1.6.0\envs\emblaze\Scripts\enaml-run-script.py",
line 5, in <module>
    sys.exit(main())
  File "c:\app\python\anaconda\1.6.0\envs\emblaze\lib\site-packages\enaml\runner
.py", line 57, in main
    exec code in ns
  File "testdev/test1.enaml", line 30, in
    main()
  File "testdev/test1.enaml", line 23, in main
    view.show()
  File "c:\app\python\anaconda\1.6.0\envs\emblaze\lib\site-packages\enaml\widget
s\window.py", line 377, in show
    self.activate_proxy()
  File "c:\app\python\anaconda\1.6.0\envs\emblaze\lib\site-packages\enaml\widget
s\toolkit_object.py", line 206, in activate_proxy
    child.activate_proxy()
  File "c:\app\python\anaconda\1.6.0\envs\emblaze\lib\site-packages\enaml\widget
s\toolkit_object.py", line 206, in activate_proxy
    child.activate_proxy()
  File "c:\app\python\anaconda\1.6.0\envs\emblaze\lib\site-packages\enaml\widget
s\toolkit_object.py", line 203, in activate_proxy
    self.activate_top_down()
  File "c:\app\python\anaconda\1.6.0\envs\emblaze\lib\site-packages\enaml\widget
s\toolkit_object.py", line 219, in activate_top_down
    self.proxy.activate_top_down()
  File "c:\app\python\anaconda\1.6.0\envs\emblaze\lib\site-packages\enaml\qt\qt_
toolkit_object.py", line 76, in activate_top_down
    self.init_widget()
  File "c:\app\python\anaconda\1.6.0\envs\emblaze\lib\site-packages\enaml\qt\qt_
field.py", line 69, in init_widget
    if d.text:
  File "c:\app\python\anaconda\1.6.0\envs\emblaze\lib\site-packages\enaml\core\d
eclarative_meta.py", line 43, in __call__
    value = engine.read(owner, name)
  File "c:\app\python\anaconda\1.6.0\envs\emblaze\lib\site-packages\enaml\core\e
xpression_engine.py", line 179, in read
    return pair.reader(owner, name)
  File "c:\app\python\anaconda\1.6.0\envs\emblaze\lib\site-packages\enaml\core\s
tandard_handlers.py", line 101, in __call__
    return call_func(func, (tr,), {}, scope)
  File "c:\app\python\anaconda\1.6.0\envs\emblaze\lib\site-packages\enaml\stdlib
\fields.enaml", line 42, in <module>
    text << converter(value)
TypeError: invalid instance type
jason-s commented 9 years ago

hmm... it looks like IntValidator will work on longs, but its minimum and maximum fields are strictly int. Would it be more appropriate to create an IntegerValidator which replaces minimum and maximum with Typed(long) and is clearly designed for integers in general rather than int or long?

https://github.com/nucleic/enaml/blob/master/enaml/validator.py

jason-s commented 9 years ago

this appears to work... one of these days I will learn how to do git pull requests :/

enamldef LongField(Field):
    """ A field that only accepts integer inputs.

    """
    attr minimum = None
    attr maximum = None
    attr base = 10
    attr value : long = 0
    attr converter << enaml.stdlib.fields._int_converters.get(base, unicode)
    text << converter(value)
    text :: self.value = long(text, base)
    validator << IntValidator(base=base, minimum=minimum, maximum=maximum)
sccolbert commented 9 years ago

This should handle ints and longs:

from numbers import Integral

class IntegralValidator(IntValidator):
    minimum = Instance(Integral)
    maximum = Instance(Integral)

enamldef IntegralField(IntField):
    attr value: Integral = 0
    validator << IntegralValidator(base=base, minimum=minimum, maximum=maximum)
jason-s commented 9 years ago

Oh, that's much simpler. Thanks! Is this something you could add to a future enaml release?

sccolbert commented 9 years ago

I'm holding off on new features for now, until we hit Atom 1.0 and we get an idea of where we to take the project.

jason-s commented 9 years ago

sounds good, it's an easy workaround. Perhaps a note in the IntField docs linking to this issue would be appropriate? The error message threw me a real curveball until I started poking around in the source. (UTSL is good when you have the time + understanding to learn, not so good when things get panicky)