Skip to content

Instantly share code, notes, and snippets.

@bazzaar
Last active October 10, 2018 21:04
Show Gist options
  • Save bazzaar/d1436636613f1f1d7e0157df204f98ec to your computer and use it in GitHub Desktop.
Save bazzaar/d1436636613f1f1d7e0157df204f98ec to your computer and use it in GitHub Desktop.
Inline::Python - Testing call method with __builtin__ getattr - fails if called repeatedly on same object / attribute combination
use Inline::Python;
my $py = Inline::Python.new();
$py.run('import matplotlib.pyplot');
class Matplotlib::Plot {
method cm {
class {
# this getattr method, called like so : 'say $plt.cm.getattr($cmap, 'N');'
method getattr($obj, $name) {
$py.call('__builtin__', 'getattr', $obj, $name);
}
method FALLBACK($name, $idx) {
$py.run("matplotlib.pyplot.cm.{$name}($idx)", :eval);
}
}.new();
}
method FALLBACK($name, |c) {
$py.call('matplotlib.pyplot', $name, |c)
}
}
class Matplotlib {
method FALLBACK($name, |c) {
$py.call('matplotlib', $name, |c)
}
}
use v6;
use lib '.';
use Matplotlib_reduced;
my $plt = Matplotlib::Plot.new;
my $cmap = $plt.get_cmap('seismic', 5);
# -- this works
#say 'Number of Colors : ' ~ $plt.cm.getattr($cmap, 'N');
#say 'Number of Colors : ' ~ $plt.cm.getattr($cmap, 'N');
# -- this fails on the 3rd call
#say 'Number of Colors : ' ~ $plt.cm.getattr($cmap, 'N');
#say 'Number of Colors : ' ~ $plt.cm.getattr($cmap, 'N');
#say 'Number of Colors : ' ~ $plt.cm.getattr($cmap, 'N');
# -- this works
#say 'Colormap Name : ' ~ $plt.cm.getattr($cmap, 'name');
#say 'Colormap Name : ' ~ $plt.cm.getattr($cmap, 'name');
# -- this fails on the 3rd call
#say 'Colormap Name : ' ~ $plt.cm.getattr($cmap, 'name');
#say 'Colormap Name : ' ~ $plt.cm.getattr($cmap, 'name');
#say 'Colormap Name : ' ~ $plt.cm.getattr($cmap, 'name');
# -- this works
#say 'Number of Colors : ' ~ $plt.cm.getattr($cmap, 'N');
#say 'Colormap Name : ' ~ $plt.cm.getattr($cmap, 'name');
# -- this fails on the 3rd call
say 'Colormap Name : ' ~ $plt.cm.getattr($cmap, 'name');
say 'Number of Colors : ' ~ $plt.cm.getattr($cmap, 'N');
say 'Number of Colors : ' ~ $plt.cm.getattr($cmap, 'N');
# -- etc....
@moritz
Copy link

moritz commented Oct 10, 2018

btw python's getattr supports a third argument which is a default value in case the attribute doesn't exist.

If you write a wrapper, maybe the simplest thing to do is to create a sentinel value Any.new as the default, and if that is returned, interpret it as not found.

@bazzaar
Copy link
Author

bazzaar commented Oct 10, 2018

More thanks 0racle, and Moritz, I definitely got way more out of this than I put in :-) I hope this thread has somehow kickstarted a future new article on your Perl6/Matplotlib blog 0racle. I agree about not bugging the Inline::Python maintainer over this when there is a work around.

It all seems so straightforward when it is explained, like you have both done in your comments, I'm not sure after a month of researching I'd have come to the same understanding :-) It's given me a whole ton of concepts and reasoning to investigate. I'll carry on with my efforts on this, and try to add some results to this gist when I have them. Thanks again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment