Rob Lanphier | 4 Apr 2010 01:43
Picon
Favicon
Gravatar

A couple of urwid-related talks I'm planning to give

Hi everyone,

I recently had talks about Urwid accepted for a couple of upcoming conferences:

LinuxFest Northwest
Bellingham, WA
April 24-25 (Exact time TBD)
http://linuxfestnorthwest.org/sessions/using-urwid-and-python-console-applications

O'Reilly's Open Source Convention (OSCON)
Portland, OR
July 22 (Thursday, 1:40pm)
Great User Interfaces in the Terminal Window:
http://www.oscon.com/oscon2010/public/schedule/detail/13958

I'm planning to represent myself as the beginner that I am rather than
an expert on urwid, drawing on my experience building jsonwidget.  I'm
of course using this as an excuse to plug jsonwidget, but I'm not
planning on making jsonwidget the central focus of either of these
talks.  That said, what I might do is through together a quick demo
using pinot.py out of jsonwidget  to create a nano/pico lookalike
clone.

Anything in particular about urwid that I should highlight for people
that are brand new to urwid?  I don't expect anyone to walk out of
either of these sessions having remembered more than 3-4 things, so
what are the most important 3-4 things people should walk away with?

Rob
(Continue reading)

Ian Ward | 4 Apr 2010 04:47
Favicon
Gravatar

Re: A couple of urwid-related talks I'm planning to give

Rob Lanphier wrote on 2010-04-03 19:43:
> Anything in particular about urwid that I should highlight for people
> that are brand new to urwid?  I don't expect anyone to walk out of
> either of these sessions having remembered more than 3-4 things, so
> what are the most important 3-4 things people should walk away with?

That's great to hear Rob!

The twisted-conch work Ali Afshar started (serve lots of ssh users with
one app) is very promising, very cool.  I hope to pull that in to Urwid
some time soon.

Also, the work to support Twisted and Glib by just changing a parameter
on the MainLoop class is extremely handy for apps that need it.

And maybe something about Urwid not trying to be TurboVision (for those
old enough to remember that)  UI concepts that work well on the console
are often different than ones that work for GUIs.  The most popular
console apps are space-efficient and keyboard-focused.  I've tried to
write Urwid for that kind of app.

Finally: pretty colours.  Urwid supports lots of them.  :-)

Ian

BTW, Are there going to be videos of either of the talks available?
Ian Ward | 4 Apr 2010 16:32
Favicon
Gravatar

Re: TreeWidget/TreeWalker class

Rob Lanphier wrote on 2010-03-24 03:06:
> Let me know if/when you'd like me to prepare it for inclusion into urwid
> mainline.  I'm happy to redo the copyright notice however you'd like to
> see it (including assigning copyright over to you...I'd just like some
> level of authorship credit), and I'm happy to prepare it as a patch to
> urwid instead of in its current standalone form, as well as doing
> whatever extra tweaking you'd need to feel comfortable taking it upstream.

I believe I made some whitespace changes browse.py that clutter the diff
 to your version.  Would you merge those changes or prepare a patch
against the latest version of browse.py?

No need for copyright assignment.  LGPL2+ is fine.

Ian
Dominic LoBue | 4 Apr 2010 21:25
Picon

Re: Bug: Signal module create backreferences

On Sat, Mar 27, 2010 at 1:39 PM, Ian Ward <ian <at> excess.org> wrote:
> Dominic LoBue wrote on 2010-03-05 03:56:
>> Ian,
>>
>> I have a working implementation. By no means is it elegant, but it works.
>>
>> Basically instead of holding onto the specific method that is to be
>> called when a signal is recieved, we instead hold onto a tuple of
>> (ref(parentwithmethod), 'methodname'). When the signal is activated,
>> we use getattr to get an instance of the method we want and then run
>> that method.
>>
>> Working examples can be found here:
>> http://gist.github.com/322577
>> http://gist.github.com/322576
>>
>
> I just want to make sure I have a good understanding of what is
> happening with these references.  The old way of tracking signals was a
> single WeakKeyDictionary:
>
> signals._connections = WeakKeyDictionary({
>    object_that_sends_signal : {
>        signal_name : [
>            (callback_function, user_argument)]}})
>
> And in common use the callback_function is a bound method on the object
> that receives the signal.
>
> This receiving object may be the last thing holding a reference to the
(Continue reading)

Ian Ward | 4 Apr 2010 22:01
Favicon
Gravatar

Re: Bug: Signal module create backreferences

Dominic LoBue wrote on 2010-04-04 15:25:
> On Sat, Mar 27, 2010 at 1:39 PM, Ian Ward <ian <at> excess.org> wrote:
>> Dominic LoBue wrote on 2010-03-05 03:56:
>>> Ian,
>>>
>>> I have a working implementation. By no means is it elegant, but it works.
>>>
>>> Basically instead of holding onto the specific method that is to be
>>> called when a signal is recieved, we instead hold onto a tuple of
>>> (ref(parentwithmethod), 'methodname'). When the signal is activated,
>>> we use getattr to get an instance of the method we want and then run
>>> that method.
>>>
>>> Working examples can be found here:
>>> http://gist.github.com/322577
>>> http://gist.github.com/322576
>>>
>> I just want to make sure I have a good understanding of what is
>> happening with these references.  The old way of tracking signals was a
>> single WeakKeyDictionary:
>>
>> signals._connections = WeakKeyDictionary({
>>    object_that_sends_signal : {
>>        signal_name : [
>>            (callback_function, user_argument)]}})
>>
>> And in common use the callback_function is a bound method on the object
>> that receives the signal.
>>
>> This receiving object may be the last thing holding a reference to the
(Continue reading)

Rob Lanphier | 4 Apr 2010 23:22
Picon
Favicon
Gravatar

Re: A couple of urwid-related talks I'm planning to give

On Sat, Apr 3, 2010 at 7:47 PM, Ian Ward <ian <at> excess.org> wrote:
> The twisted-conch work Ali Afshar started (serve lots of ssh users with
> one app) is very promising, very cool.  I hope to pull that in to Urwid
> some time soon.
>
> Also, the work to support Twisted and Glib by just changing a parameter
> on the MainLoop class is extremely handy for apps that need it.

I'll make sure I at least briefly touch on those.  Would it be fair to
say that the main benefit of a GLib event loop is that it makes it
much easier to pull in the glib bindings and do things like listen for
d-bus events?  What's a good example of a theoretical but practical
application you would use to get people excited about using a GLib
main loop?

> And maybe something about Urwid not trying to be TurboVision (for those
> old enough to remember that)  UI concepts that work well on the console
> are often different than ones that work for GUIs.  The most popular
> console apps are space-efficient and keyboard-focused.  I've tried to
> write Urwid for that kind of app.

That's good to know.  I'm going to have to think about delivering that
message in a way that doesn't conflict with the message I've been
thinking about.  I'll definitely make it clear that you aren't trying
to make this into TurboVision, but part of what interested me in
giving this talk is to encourage people to write applications that are
more immediately intuitive than many of the console apps that are
popular today.  I don't think what I'm saying is at odds with your
point, but let me see if what I'm thinking about here rubs you the
wrong way.
(Continue reading)

Andrew Psaltis | 4 Apr 2010 23:35
Picon

Re: A couple of urwid-related talks I'm planning to give

I implemented the GlibEventLoop was actually implemented so urwid applications could talk to DBus in a nice way.

A real-life example of an application that could use it is wicd-curses, an urwid frontend to wicd that I wrote.  It should help developers avoid the various chaos that occurred when I first figured out how to use DBus in urwid apps.  I don't actually use the urwid.MainLoop class in wicd-curses to preserve compatibility with earlier urwid versions, but the same idea persists.

~Andrew

On Sun, Apr 4, 2010 at 5:22 PM, Rob Lanphier <robla <at> robla.net> wrote:
On Sat, Apr 3, 2010 at 7:47 PM, Ian Ward <ian <at> excess.org> wrote:
> The twisted-conch work Ali Afshar started (serve lots of ssh users with
> one app) is very promising, very cool.  I hope to pull that in to Urwid
> some time soon.
>
> Also, the work to support Twisted and Glib by just changing a parameter
> on the MainLoop class is extremely handy for apps that need it.

I'll make sure I at least briefly touch on those.  Would it be fair to
say that the main benefit of a GLib event loop is that it makes it
much easier to pull in the glib bindings and do things like listen for
d-bus events?  What's a good example of a theoretical but practical
application you would use to get people excited about using a GLib
main loop?

> And maybe something about Urwid not trying to be TurboVision (for those
> old enough to remember that)  UI concepts that work well on the console
> are often different than ones that work for GUIs.  The most popular
> console apps are space-efficient and keyboard-focused.  I've tried to
> write Urwid for that kind of app.

That's good to know.  I'm going to have to think about delivering that
message in a way that doesn't conflict with the message I've been
thinking about.  I'll definitely make it clear that you aren't trying
to make this into TurboVision, but part of what interested me in
giving this talk is to encourage people to write applications that are
more immediately intuitive than many of the console apps that are
popular today.  I don't think what I'm saying is at odds with your
point, but let me see if what I'm thinking about here rubs you the
wrong way.

I think up until recently, the payoff for investing in console apps
has been pretty low (i.e. 8 hours of ncurses programming doesn't get
you much of a user interface, and there's little that you get "for
free").  Now that it's not that hard to knock out a reasonably looking
user interface, there's no reason why the distros shouldn't make
console usability part of their general usability push, especially
since good console apps would probably be most useful to the big
distros highest paying customers (Linux servers account for *way* more
revenue than Linux desktops, and "the cloud" is shaping up as the next
big battleground).  Usable console apps are much easier to create now,
so why not actually try to make more of them, and make the ones we
have more usable?

As I think you're saying here, though, "usable" doesn't necessarily
mean ASCII-art borders, drop shadows, and a mouse-centric UI.  People
using SSH may very easily still be constrained by what's possible over
vt102, so making a lot of assumptions about I/O devices and screen
real estate may easily result in something less usable.

Is that compatible with what you see as the vision for the urwid project?

> Finally: pretty colours.  Urwid supports lots of them.  :-)

Ah yes, the colors!  I'll make sure that's obvious.

> BTW, Are there going to be videos of either of the talks available?

I'm not sure.  The last time I was at LFNW (in 2008), there were some
rooms that had video equipment, and some that didn't, so it depended
on where you were.  OSCON seems to typically only put videos up of the
keynotes, so I don't think that one is going to be available, but now
that video is getting so cheap and easy to shoot, maybe this year
they'll expand out.

Rob

_______________________________________________
Urwid mailing list
Urwid <at> lists.excess.org
http://lists.excess.org/mailman/listinfo/urwid

_______________________________________________
Urwid mailing list
Urwid <at> lists.excess.org
http://lists.excess.org/mailman/listinfo/urwid
Ian Ward | 5 Apr 2010 00:59
Favicon
Gravatar

Re: A couple of urwid-related talks I'm planning to give

Rob Lanphier wrote on 2010-04-04 17:22:
> On Sat, Apr 3, 2010 at 7:47 PM, Ian Ward <ian <at> excess.org> wrote:
>> The twisted-conch work Ali Afshar started (serve lots of ssh users with
>> one app) is very promising, very cool.  I hope to pull that in to Urwid
>> some time soon.
>>
>> Also, the work to support Twisted and Glib by just changing a parameter
>> on the MainLoop class is extremely handy for apps that need it.
> 
> I'll make sure I at least briefly touch on those.  Would it be fair to
> say that the main benefit of a GLib event loop is that it makes it
> much easier to pull in the glib bindings and do things like listen for
> d-bus events?  What's a good example of a theoretical but practical
> application you would use to get people excited about using a GLib
> main loop?

Andrew mentioned his wicd-curses program, and I believe D-Bus is the big
thing selling point for GLib.

Twisted, of course has support for almost any network protocol
(including D-Bus messages) if you're willing to write your apps the
Twisted way.

I didn't mention the default event loop based on select() that can work
well with the more common threaded or multiprocess way of getting work
done without tying up the UI.  Finally if you really know best you can
also just write your own main loop (the way it was done before 0.9.9.)

Or in fewer words, "yes, it will work with that".

>> And maybe something about Urwid not trying to be TurboVision (for those
>> old enough to remember that)  UI concepts that work well on the console
>> are often different than ones that work for GUIs.  The most popular
>> console apps are space-efficient and keyboard-focused.  I've tried to
>> write Urwid for that kind of app.
...
> As I think you're saying here, though, "usable" doesn't necessarily
> mean ASCII-art borders, drop shadows, and a mouse-centric UI.  People
> using SSH may very easily still be constrained by what's possible over
> vt102, so making a lot of assumptions about I/O devices and screen
> real estate may easily result in something less usable.
> 
> Is that compatible with what you see as the vision for the urwid project?

Certainly.  I see mouse-focused GUI-inspired interfaces as just a small
part of what is possible with Urwid.

But, don't just listen to me.  I wrote most of Urwid so of course I
think the newest features are the most interesting.  The perspective of
a new user is probably better for selecting features to highlight.

Ian
Dominic LoBue | 5 Apr 2010 03:20
Picon

Re: Bug: Signal module create backreferences

On Sun, Apr 4, 2010 at 1:01 PM, Ian Ward <ian <at> excess.org> wrote:
> Dominic LoBue wrote on 2010-04-04 15:25:
>> On Sat, Mar 27, 2010 at 1:39 PM, Ian Ward <ian <at> excess.org> wrote:
>>> Dominic LoBue wrote on 2010-03-05 03:56:
>>>> Ian,
>>>>
>>>> I have a working implementation. By no means is it elegant, but it works.
>>>>
>>>> Basically instead of holding onto the specific method that is to be
>>>> called when a signal is recieved, we instead hold onto a tuple of
>>>> (ref(parentwithmethod), 'methodname'). When the signal is activated,
>>>> we use getattr to get an instance of the method we want and then run
>>>> that method.
>>>>
>>>> Working examples can be found here:
>>>> http://gist.github.com/322577
>>>> http://gist.github.com/322576
>>>>
>>> I just want to make sure I have a good understanding of what is
>>> happening with these references.  The old way of tracking signals was a
>>> single WeakKeyDictionary:
>>>
>>> signals._connections = WeakKeyDictionary({
>>>    object_that_sends_signal : {
>>>        signal_name : [
>>>            (callback_function, user_argument)]}})
>>>
>>> And in common use the callback_function is a bound method on the object
>>> that receives the signal.
>>>
>>> This receiving object may be the last thing holding a reference to the
>>> sending object, however when the receiving object is removed the bound
>>> method keeps it alive, in turn keeping the sending object alive and
>>> circular references in _connections are never removed.
>>>
>>> The same thing happens with the current code, except _connections is now
>>> in the sending object and nothing points to the dead objects, so I
>>> assume they would eventually get picked up by the garbage collector.
>>>
>>> (please correct me if I'm wrong)
>>>
>>
>> Ian,
>>
>> The solution actually has nothing to do with where the bound method is
>> being kept. Keeping the signal -> method mapping in one place is
>> preference; I think it is a cleaner solution overall.
>
> I agree with the preference for keeping all the mappings in one place.
> In my (new) tests, I haven't been able to make an implementation with
> everything together in one place work:
> http://excess.org/urwid/browser/reference_test.py
>
> Specifically the last test always fails and Urwid leaks memory. *
>
>> The problem is that bound methods reference the class they are bound
>> to, and in so doing they keep that class alive. The WeakKeyDictionary
>> doesn't do anything (at least in my case).
>
> s/class/object
>
>> To give an example, say the object_that_sends_signal from your example
>> is a property of object_that_receives_signal, and callback_function is
>> a bound method of object_that_receives_signal. This is a circular
>> reference: object_that_receives_signal references
>> object_that_sends_signal, keeping the dictionary entries alive; and
>> the bound method callback_function references
>> object_that_receives_signal, keeping it alive as well. All the nesting
>> that the bound_method is below prevents the weak reference from
>> working.
>
> * Right, but maybe we're working under different assumptions.  I think
> it's ok for the only reference to callback function to be via a signal.
>  Won't your code delete the object_that_receives_signal if the only
> reference to object_that_receives_signal is from a signal?
>

Nope. That's what the script I included in my first email proved.

>>> One problem with your solution is that it only helps if the
>>> callback_function is a bound method.  What if it's a normal function
>>> that happened to pull in a reference to the sending object from its
>>> enclosing scope?
>>
>> Can you give an example of what you mean?
>>
>
> Idle speculation, I haven't made it work(fail?) yet.  Something along
> the lines of:
>
>    def setup_my_signal_handler():
>        foo = ObjectThatSendsSignal()
>        def signal_handler(f):
>            print foo, f
>        urwid.connect_signal(foo, 'some_signal', signal_handler)
>
> where signal_handler() has a reference to foo inherited from the
> enclosing function.
>

Ohh, cool. I'll have to try that.

> Ian
>
> _______________________________________________
> Urwid mailing list
> Urwid <at> lists.excess.org
> http://lists.excess.org/mailman/listinfo/urwid
>

Okay, just tried it using my fix and I get a bug where the nested
function is released and the weak reference breaks:
python circularsignals.py
child phones home
Traceback (most recent call last):
  File "circularsignals.py", line 27, in <module>
    a.something.do_emit()
  File "circularsignals.py", line 8, in do_emit
    emit_signal(self, 'something')
  File "/tank/projects/urwid/urwid/signals.py", line 77, in emit
    result |= bool(callback(*args_copy))
ReferenceError: weakly-referenced object no longer exists

For my test I just modified the "my_object" class from the code in my
original email to this:
class my_object(object):
    __metaclass__ = MetaSignals
    signals = ['something']

    def __init__(self):
        def nest_func():
            print "nested!"

        self.something = my_other_object()
        connect_signal(self.something, 'something', self.melse)
        connect_signal(self.something, 'something', nest_func)

    def melse(self):
        print 'child phones home'

I fixed the ducktype implementation to not proxy anything other than
methods and pushed it to my branch.

--

-- 
Dominic LoBue
Ian Ward | 5 Apr 2010 04:25
Favicon
Gravatar

Re: Bug: Signal module create backreferences

Dominic LoBue wrote on 2010-04-04 21:20:
> I fixed the ducktype implementation to not proxy anything other than
> methods and pushed it to my branch.

Here's an example of behaviour that I don't want with your current
signals_ducktype branch:

import urwid
b = urwid.Button("test")
class Foo(object):
    def react(self, b):
        print "reacting"

f = Foo()
urwid.connect_signal(b, 'click', f.react)
del f
b.keypress((10,), ' ') # this should print "reacting"

Instead it causes an error indicating that the callback has been
removed.  That's no good: a signal should be enough to keep the function
it's referencing alive.

Ian

Gmane