Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork7.9k
Reset the available animation movie writer on rcParam change#5628
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
e3e2be9
6a01829
6c6cf91
96b439a
9b61b34
33f564a
e783867
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -64,6 +64,12 @@ | ||
class MovieWriterRegistry(object): | ||
def __init__(self): | ||
self.avail = dict() | ||
self._registered = dict() | ||
self._dirty = False | ||
def set_dirty(self): | ||
"""Sets a flag to re-setup the writers""" | ||
self._dirty = True | ||
# Returns a decorator that can be used on classes to register them under | ||
# a name. As in: | ||
@@ -72,19 +78,36 @@ def __init__(self): | ||
# pass | ||
def register(self, name): | ||
def wrapper(writerClass): | ||
self._registered[name] = writerClass | ||
if writerClass.isAvailable(): | ||
self.avail[name] = writerClass | ||
return writerClass | ||
return wrapper | ||
def ensure_not_dirty(self): | ||
"""If dirty, reasks the writers if they are available""" | ||
if self._dirty: | ||
self.reset_available_writers() | ||
def reset_available_writers(self): | ||
"""Reset the available state of all registered writers""" | ||
self.avail = {} | ||
for name, writerClass in self._registered.items(): | ||
if writerClass.isAvailable(): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. BTW: should that be "is_available"? It's the only method in that class(es) which use CamelCase instead of underscores... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. It is annoying, but I don't think worth breaking user code over. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. At most, we can rename and add an alias | ||
self.avail[name] = writerClass | ||
self._dirty = False | ||
def list(self): | ||
''' Get a list of available MovieWriters.''' | ||
self.ensure_not_dirty() | ||
return list(self.avail.keys()) | ||
def is_available(self, name): | ||
self.ensure_not_dirty() | ||
return name in self.avail | ||
def __getitem__(self, name): | ||
self.ensure_not_dirty() | ||
if not self.avail: | ||
raise RuntimeError("No MovieWriters available!") | ||
return self.avail[name] | ||
@@ -315,10 +338,11 @@ def isAvailable(cls): | ||
Check to see if a MovieWriter subclass is actually available by | ||
running the commandline tool. | ||
''' | ||
bin_path = cls.bin_path() | ||
if not bin_path: | ||
return False | ||
try: | ||
p = subprocess.Popen(bin_path, | ||
shell=False, | ||
stdout=subprocess.PIPE, | ||
stderr=subprocess.PIPE, | ||
@@ -432,9 +456,19 @@ def finish(self): | ||
# Check error code for creating file here, since we just run | ||
# the process here, rather than having an open pipe. | ||
if self._proc.returncode: | ||
try: | ||
stdout = [s.decode() for s in self._proc._stdout_buff] | ||
stderr = [s.decode() for s in self._proc._stderr_buff] | ||
verbose.report("MovieWriter.finish: stdout: %s" % stdout, | ||
level='helpful') | ||
verbose.report("MovieWriter.finish: stderr: %s" % stderr, | ||
level='helpful') | ||
except Exception as e: | ||
pass | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. This is not my finest code, but it works on py35... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. This is just to provide improved debugging feed back right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. yes, when the called converter fails and the user adds the Unfortunately, it doesn't work for the unittests unless I add such a | ||
msg = ('Error creating movie, return code: ' + | ||
str(self._proc.returncode) + | ||
' Try setting mpl.verbose.set_level("helpful")') | ||
raise RuntimeError(msg) | ||
def cleanup(self): | ||
MovieWriter.cleanup(self) | ||
@@ -619,12 +653,28 @@ def _init_from_registry(cls): | ||
binpath = '' | ||
rcParams[cls.exec_key] = rcParamsDefault[cls.exec_key] = binpath | ||
@classmethod | ||
def isAvailable(cls): | ||
''' | ||
Check to see if a ImageMagickWriter is actually available | ||
Done by first checking the windows registry (if applicable) and then | ||
running the commandline tool. | ||
''' | ||
bin_path = cls.bin_path() | ||
if bin_path == "convert": | ||
cls._init_from_registry() | ||
return super(ImageMagickBase, cls).isAvailable() | ||
ImageMagickBase._init_from_registry() | ||
# Note: the base classes need to be in that order to get | ||
# isAvailable() from ImageMagickBase called and not the | ||
# one from MovieWriter. The latter is then called by the | ||
# former. | ||
@writers.register('imagemagick') | ||
class ImageMagickWriter(ImageMagickBase, MovieWriter): | ||
def _args(self): | ||
return ([self.bin_path(), | ||
'-size', '%ix%i' % self.frame_size, '-depth', '8', | ||
@@ -633,8 +683,12 @@ def _args(self): | ||
+ self.output_args) | ||
# Note: the base classes need to be in that order to get | ||
# isAvailable() from ImageMagickBase called and not the | ||
# one from MovieWriter. The latter is then called by the | ||
# former. | ||
@writers.register('imagemagick_file') | ||
class ImageMagickFileWriter(ImageMagickBase, FileMovieWriter): | ||
supported_formats = ['png', 'jpeg', 'ppm', 'tiff', 'sgi', 'bmp', | ||
'pbm', 'raw', 'rgba'] | ||