MEP13 - python containers

I have created a very preliminary MEP for the possible move to properties:

https://github.com/matplotlib/matplotlib/wiki/MEP13

Please take a look at it and discuss. As I said, this is very preliminary. Everything is subject to change.

Hi Todd,

I agree with the principle of properties - it will make much of the mpl codebase (and user code) more pythonic, so thanks for proposing this.

Would you be able to give an example of how you propose setters such as Axes.set_xlim might make use of properties. The particular example I have picked uses keywords to determine the behaviours of the method itself:

def set_xlim(self, left=None, right=None, emit=True, auto=False, **kw):

For me, the backwards compatibility issue is the key blocker to this MEP. Would you mind providing some concrete examples (perhaps using the set_xlim method as a focus point)?

Cheers,

Phil

···

On 16 January 2013 21:00, Todd <toddrjen@…149…> wrote:

I have created a very preliminary MEP for the possible move to properties:

https://github.com/matplotlib/matplotlib/wiki/MEP13

Please take a look at it and discuss. As I said, this is very preliminary. Everything is subject to change.


Master Java SE, Java EE, Eclipse, Spring, Hibernate, JavaScript, jQuery

and much more. Keep your Java skills current with LearnJavaNow -

200+ hours of step-by-step video tutorials by Java experts.

SALE $49.99 this month only – learn more at:

http://p.sf.net/sfu/learnmore_122612


Matplotlib-devel mailing list

Matplotlib-devel@lists.sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Methods like that will be a problem. I see two possible approaches (which
are not mutually exclusive):

1. keep the set_xlim method for more sophisticated cases.
2. split the set_xlim method into several methods

Frankly I am not sure deprecating the existing setter and getter methods is
really called for. It may not be worth the trouble for users. That is why
I said everything in the MEP is very tentative.

For approach 1, we would keep the current method, but also have another
method:

@xlim.setter
def xlim(self, lims):
    ...

so for the basic case, just setting the lims, you would do:

axesobj.xlims = (leftval, rightval)

For approach 2, you would have additionally have (there is already an
autoscale_x_on method):

@autoscale_x.setter
def autoscale_x(self, auto):
    ...

@emit_xlim.setter
def emit_xlim(self, emit):
    ...

@xlim_left.setter
def xlim_left(self, left):
    ...

@xlim_right.setter
def xlim_right(self, rigth):
    ...

(or you could do some python-fu to allow you to assign values to the
xlim[0] and xlim[1])

This would require setting three separate attributes. However, we would
already have the autoscale_x property.

In my opinion breaking up the API into separate calls would be a cleaner
approach anyway. Setters and getters should be setters and getters, they
shouldn't be modifying other unrelated values. But that does not mean we
have to remove the existing approach.

···

On Thu, Jan 17, 2013 at 10:43 AM, Phil Elson <pelson.pub@...149...> wrote:

Hi Todd,

I agree with the principle of properties - it will make much of the mpl
codebase (and user code) more pythonic, so thanks for proposing this.

Would you be able to give an example of how you propose setters such as
Axes.set_xlim might make use of properties. The particular example I have
picked uses keywords to determine the behaviours of the method itself:

def set_xlim(self, left=None, right=None, emit=True, auto=False, **kw):
    ...

For me, the backwards compatibility issue is the key blocker to this MEP.
Would you mind providing some concrete examples (perhaps using the set_xlim
method as a focus point)?

Cheers,

Phil

I've added examples of two examples of difficult cases to the MEP. I've
also added more specific details of how to deal with them.

The MEP is still written under the assumption that we will ultimately
deprecate the existing setter and getter methods but, as I said, whether
this is the best approach is highly questionable.

···

On Thu, Jan 17, 2013 at 11:30 AM, Todd <toddrjen@...149...> wrote:

On Thu, Jan 17, 2013 at 10:43 AM, Phil Elson <pelson.pub@...149...> wrote:

Hi Todd,

I agree with the principle of properties - it will make much of the mpl
codebase (and user code) more pythonic, so thanks for proposing this.

Would you be able to give an example of how you propose setters such as
Axes.set_xlim might make use of properties. The particular example I
have picked uses keywords to determine the behaviours of the method itself:

def set_xlim(self, left=None, right=None, emit=True, auto=False, **kw):
    ...

For me, the backwards compatibility issue is the key blocker to this MEP.
Would you mind providing some concrete examples (perhaps using the set_xlim
method as a focus point)?

Cheers,

Phil

Methods like that will be a problem. I see two possible approaches (which
are not mutually exclusive):

1. keep the set_xlim method for more sophisticated cases.
2. split the set_xlim method into several methods

Frankly I am not sure deprecating the existing setter and getter methods
is really called for. It may not be worth the trouble for users. That is
why I said everything in the MEP is very tentative.

For approach 1, we would keep the current method, but also have another
method:

@xlim.setter
def xlim(self, lims):
    ...

so for the basic case, just setting the lims, you would do:

axesobj.xlims = (leftval, rightval)

For approach 2, you would have additionally have (there is already an
autoscale_x_on method):

@autoscale_x.setter
def autoscale_x(self, auto):
    ...

@emit_xlim.setter
def emit_xlim(self, emit):
    ...

@xlim_left.setter
def xlim_left(self, left):
    ...

@xlim_right.setter
def xlim_right(self, rigth):
    ...

(or you could do some python-fu to allow you to assign values to the
xlim[0] and xlim[1])

This would require setting three separate attributes. However, we would
already have the autoscale_x property.

In my opinion breaking up the API into separate calls would be a cleaner
approach anyway. Setters and getters should be setters and getters, they
shouldn't be modifying other unrelated values. But that does not mean we
have to remove the existing approach.

My take is that things like xlims, titles and such probably shouldn’t be made into properties quite yet. They are more complex beasts. I am more concerned about the simplification of the API w.r.t. the attributes of the artist objects such as edgecolor, linewidth, facecolor, fontsize, etc… It is these things down at the OO level that feels very klunky.

Cheers!
Ben Root

···

On Thu, Jan 17, 2013 at 11:30 AM, Todd <toddrjen@…322…9…> wrote:

On Thu, Jan 17, 2013 at 10:43 AM, Phil Elson <pelson.pub@…149…> wrote:

Hi Todd,

I agree with the principle of properties - it will make much of the mpl codebase (and user code) more pythonic, so thanks for proposing this.

Would you be able to give an example of how you propose setters such as Axes.set_xlim might make use of properties. The particular example I have picked uses keywords to determine the behaviours of the method itself:

def set_xlim(self, left=None, right=None, emit=True, auto=False, **kw):

For me, the backwards compatibility issue is the key blocker to this MEP. Would you mind providing some concrete examples (perhaps using the set_xlim method as a focus point)?

Cheers,

Phil

Methods like that will be a problem. I see two possible approaches (which are not mutually exclusive):

  1. keep the set_xlim method for more sophisticated cases.

  2. split the set_xlim method into several methods

Frankly I am not sure deprecating the existing setter and getter methods is really called for. It may not be worth the trouble for users. That is why I said everything in the MEP is very tentative.

For approach 1, we would keep the current method, but also have another method:

@xlim.setter

def xlim(self, lims):

so for the basic case, just setting the lims, you would do:

axesobj.xlims = (leftval, rightval)

For approach 2, you would have additionally have (there is already an autoscale_x_on method):

@autoscale_x.setter

def autoscale_x(self, auto):

def emit_xlim(self, emit):

def xlim_left(self, left):

def xlim_right(self, rigth):

@emit_xlim.setter

@xlim_left.setter

@xlim_right.setter

(or you could do some python-fu to allow you to assign values to the xlim[0] and xlim[1])

This would require setting three separate attributes. However, we would already have the autoscale_x property.

In my opinion breaking up the API into separate calls would be a cleaner approach anyway. Setters and getters should be setters and getters, they shouldn’t be modifying other unrelated values. But that does not mean we have to remove the existing approach.

I’ve added examples of two examples of difficult cases to the MEP. I’ve also added more specific details of how to deal with them.

The MEP is still written under the assumption that we will ultimately deprecate the existing setter and getter methods but, as I said, whether this is the best approach is highly questionable.

It seens that discussion of properties has died off, but I see it as a very
important implementation for 2 reasons:

1. It will help with the implementation of stylsheets and a DOM-type model
as proposed in MEP25 and MEP26

2. The act of working through the code to add properties exposes any
inconsistencies and vulnerabilities.

I have been adding properties to my fork of MPL as part of the development
of a visualisation tool.
https://github.com/JamesRamm/matplotlib/tree/master/lib/matplotlib

text.py and font-manager.py are completely 'propertyfied' and I have done a
fair amount of work on artist.py, _axes.py, _base.py and axis.py

Axis.py in particular is a sticking point, which has been difficult to add
properties to. In any case, the fact that the Ticker() class exists points
to some problems with this part of the code in particular. Ticker holds
references too (or rather, the locator and formatter properties of Ticker)
the axis object, yet is initialised within the initialisation of the axis
class...
This can be a problem.

Looking through ticker.py, it seems that in most places, the need for a
reference to axis is not necessary.

Functions such as zoom and pan, which are within the Locator class in
ticker, should actually be implemented in axis.py (as I have in my fork) as
they have no dependency on Locator.

Anyway, adding properties is a large job. I will probably implement them
completely as part of my work, but:

- Backwards compatibility will be broken
- The resulting library will probably look a whole lot different to MPL.

For those reasons, I doubt I will ever make a pull request for my fork and I
will neglect areas such as the pyplot/pylab interfaces. IMO, have a nice
simple, object oriented API negates the need for such interfaces and I am
not concerned with keeping a 'matlab-user' community happy...

I don't see the API of MPL changing this much anytime soon (or anytime
really), but in order to keep up with newer libraries it probably should,
and should not be concerned about backwards compatibility when it does...

···

--
View this message in context: http://matplotlib.1069221.n5.nabble.com/MEP13-python-containers-tp40248p43730.html
Sent from the matplotlib - devel mailing list archive at Nabble.com.

I only took a brief look at that branch, but two comments

1) can you clean up your git history, you are adding 20k new lines (of
mostly freetype and random files that should not be tracked)
2) can you split the propertify work up into chunks that are easier to review?

···

On Thu, Jul 31, 2014 at 7:16 AM, jamesramm <jamessramm@...149...> wrote:

It seens that discussion of properties has died off, but I see it as a very
important implementation for 2 reasons:

1. It will help with the implementation of stylsheets and a DOM-type model
as proposed in MEP25 and MEP26

2. The act of working through the code to add properties exposes any
inconsistencies and vulnerabilities.

I have been adding properties to my fork of MPL as part of the development
of a visualisation tool.
https://github.com/JamesRamm/matplotlib/tree/master/lib/matplotlib

text.py and font-manager.py are completely 'propertyfied' and I have done a
fair amount of work on artist.py, _axes.py, _base.py and axis.py

Axis.py in particular is a sticking point, which has been difficult to add
properties to. In any case, the fact that the Ticker() class exists points
to some problems with this part of the code in particular. Ticker holds
references too (or rather, the locator and formatter properties of Ticker)
the axis object, yet is initialised within the initialisation of the axis
class...
This can be a problem.

Looking through ticker.py, it seems that in most places, the need for a
reference to axis is not necessary.

Functions such as zoom and pan, which are within the Locator class in
ticker, should actually be implemented in axis.py (as I have in my fork) as
they have no dependency on Locator.

Anyway, adding properties is a large job. I will probably implement them
completely as part of my work, but:

- Backwards compatibility will be broken
- The resulting library will probably look a whole lot different to MPL.

For those reasons, I doubt I will ever make a pull request for my fork and I
will neglect areas such as the pyplot/pylab interfaces. IMO, have a nice
simple, object oriented API negates the need for such interfaces and I am
not concerned with keeping a 'matlab-user' community happy...

I don't see the API of MPL changing this much anytime soon (or anytime
really), but in order to keep up with newer libraries it probably should,
and should not be concerned about backwards compatibility when it does...

--
View this message in context: http://matplotlib.1069221.n5.nabble.com/MEP13-python-containers-tp40248p43730.html
Sent from the matplotlib - devel mailing list archive at Nabble.com.

------------------------------------------------------------------------------
Infragistics Professional
Build stunning WinForms apps today!
Reboot your WinForms applications with our WinForms controls.
Build a bridge from your legacy apps to the future.
http://pubads.g.doubleclick.net/gampad/clk?id=153845071&iu=/4140/ostg.clktrk
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

--
Thomas Caswell
tcaswell@...149...

Thomas Caswell wrote

I only took a brief look at that branch, but two comments

1) can you clean up your git history, you are adding 20k new lines (of
mostly freetype and random files that should not be tracked)
2) can you split the propertify work up into chunks that are easier to
review?

Yes. This is mostly my inability to use git (I've not particular used it
before). I'll have to look up how to clean the history and 'unversion' the
unneeded freetype stuff.

As it is already committed to my branch, im not sure the existing stuff can
be split into chunks? But I will make issues and split up the next lumps of
work.

I'll post back when it is (hopefully) cleaner

···

--
View this message in context: http://matplotlib.1069221.n5.nabble.com/MEP13-python-containers-tp40248p43732.html
Sent from the matplotlib - devel mailing list archive at Nabble.com.

Git lets you re-write history pretty extensively. If you use a tool
on top of git (I use magit in emacs) you can selectively commit hunks
one or two at a time. At a minimum split it up by file. You are
going to have to do some force-pushing anyway.

Making the PRs as small as reasonable makes reviewing much easier. It
makes it possible to go through the entire PR in one sitting and it
allows the un-controversial stuff to be merged as quickly as possible
without being held up by other parts. The longer large PRs hang
around the greater the chance they will accumulate conflicts with
other PRs and require a re-base (re-basing a 500+ line diff is
_incredibly_ painful).

Tom

···

On Thu, Jul 31, 2014 at 11:09 AM, jamesramm <jamessramm@...149...> wrote:

Thomas Caswell wrote

I only took a brief look at that branch, but two comments

1) can you clean up your git history, you are adding 20k new lines (of
mostly freetype and random files that should not be tracked)
2) can you split the propertify work up into chunks that are easier to
review?

Yes. This is mostly my inability to use git (I've not particular used it
before). I'll have to look up how to clean the history and 'unversion' the
unneeded freetype stuff.

As it is already committed to my branch, im not sure the existing stuff can
be split into chunks? But I will make issues and split up the next lumps of
work.

I'll post back when it is (hopefully) cleaner

--
View this message in context: http://matplotlib.1069221.n5.nabble.com/MEP13-python-containers-tp40248p43732.html
Sent from the matplotlib - devel mailing list archive at Nabble.com.

------------------------------------------------------------------------------
Infragistics Professional
Build stunning WinForms apps today!
Reboot your WinForms applications with our WinForms controls.
Build a bridge from your legacy apps to the future.
http://pubads.g.doubleclick.net/gampad/clk?id=153845071&iu=/4140/ostg.clktrk
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

--
Thomas Caswell
tcaswell@...149...

I would suggest create a new branch, though. You can create a new branch from the old one, then make your changes there. That way if you mess up something you still have the original to fall back on.

···

On Thu, Jul 31, 2014 at 5:15 PM, Thomas Caswell <tcaswell@…149…> wrote:

Git lets you re-write history pretty extensively. If you use a tool

on top of git (I use magit in emacs) you can selectively commit hunks

one or two at a time. At a minimum split it up by file. You are

going to have to do some force-pushing anyway.

Making the PRs as small as reasonable makes reviewing much easier. It

makes it possible to go through the entire PR in one sitting and it

allows the un-controversial stuff to be merged as quickly as possible

without being held up by other parts. The longer large PRs hang

around the greater the chance they will accumulate conflicts with

other PRs and require a re-base (re-basing a 500+ line diff is

incredibly painful).

Tom

On Thu, Jul 31, 2014 at 11:09 AM, jamesramm <jamessramm@…149…> wrote:

Thomas Caswell wrote

I only took a brief look at that branch, but two comments

  1. can you clean up your git history, you are adding 20k new lines (of

mostly freetype and random files that should not be tracked)

  1. can you split the propertify work up into chunks that are easier to

review?

Yes. This is mostly my inability to use git (I’ve not particular used it

before). I’ll have to look up how to clean the history and ‘unversion’ the

unneeded freetype stuff.

As it is already committed to my branch, im not sure the existing stuff can

be split into chunks? But I will make issues and split up the next lumps of

work.

I’ll post back when it is (hopefully) cleaner

View this message in context: http://matplotlib.1069221.n5.nabble.com/MEP13-python-containers-tp40248p43732.html

Sent from the matplotlib - devel mailing list archive at Nabble.com.


Infragistics Professional

Build stunning WinForms apps today!

Reboot your WinForms applications with our WinForms controls.

Build a bridge from your legacy apps to the future.

http://pubads.g.doubleclick.net/gampad/clk?id=153845071&iu=/4140/ostg.clktrk


Matplotlib-devel mailing list

Matplotlib-devel@lists.sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Thomas Caswell

tcaswell@…149…


Infragistics Professional

Build stunning WinForms apps today!

Reboot your WinForms applications with our WinForms controls.

Build a bridge from your legacy apps to the future.

http://pubads.g.doubleclick.net/gampad/clk?id=153845071&iu=/4140/ostg.clktrk


Matplotlib-devel mailing list

Matplotlib-devel@lists.sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-devel