提交 a8b47a81 authored 作者: Olivier Delalleau's avatar Olivier Delalleau

Refactored try / except / finally for Python 2.4 compatibility

上级 481bd2ef
...@@ -734,115 +734,117 @@ class ModuleCache(object): ...@@ -734,115 +734,117 @@ class ModuleCache(object):
raise raise
try: try:
compile_steps = fn(location=location).__iter__() # Embedding two try statements for Python 2.4 compatibility
# (cannot do try / except / finally).
# Check if we already know a module with the same hash. If we try:
# do, then there is no need to even compile it. compile_steps = fn(location=location).__iter__()
duplicated_module = False
# The first compilation step is to yield the source code. # Check if we already know a module with the same hash. If we
src_code = compile_steps.next() # do, then there is no need to even compile it.
module_hash = get_module_hash(src_code, key) duplicated_module = False
if module_hash in self.module_hash_to_key_data: # The first compilation step is to yield the source code.
debug("Duplicated module! Will re-use the previous one") src_code = compile_steps.next()
duplicated_module = True module_hash = get_module_hash(src_code, key)
# Load the already existing module. if module_hash in self.module_hash_to_key_data:
key_data = self.module_hash_to_key_data[module_hash] debug("Duplicated module! Will re-use the previous one")
# Note that we do not pass the `fn` argument, since it duplicated_module = True
# should not be used considering that the module should # Load the already existing module.
# already be compiled. key_data = self.module_hash_to_key_data[module_hash]
module = self.module_from_key(key=None, key_data=key_data) # Note that we do not pass the `fn` argument, since it
name = module.__file__ # should not be used considering that the module should
# Add current key to the set of keys associated to the same # already be compiled.
# module. We only save the KeyData object of versioned module = self.module_from_key(key=None, key_data=key_data)
# modules. name = module.__file__
try: # Add current key to the set of keys associated to the same
key_data.add_key(key, save_pkl=bool(_version)) # module. We only save the KeyData object of versioned
key_broken = False # modules.
except cPickle.PicklingError:
# This should only happen if we tried to save the
# pickled file.
assert _version
# The key we are trying to add is broken: we will not
# add it after all.
key_data.remove_key(key)
key_broken = True
if (_version and not key_broken and
self.check_for_broken_eq):
self.check_key(key, key_data.key_pkl)
# We can delete the work directory.
_rmtree(location, ignore_nocleanup=True,
msg='temporary workdir of duplicated module')
else:
# Will fail if there is an error compiling the C code.
# The exception will be caught and the work dir will be
# deleted.
while True:
try:
# The module should be returned by the last
# step of the compilation.
module = compile_steps.next()
except StopIteration:
break
# Obtain path to the '.so' module file.
name = module.__file__
debug("Adding module to cache", key, name)
assert name.startswith(location)
assert name not in self.module_from_name
# Changing the hash of the key is not allowed during
# compilation. That is the only cause found that makes the
# following assert fail.
assert hash(key) == hash_key
assert key not in self.entry_from_key
key_pkl = os.path.join(location, 'key.pkl')
assert not os.path.exists(key_pkl)
key_data = KeyData(
keys=set([key]),
module_hash=module_hash,
key_pkl=key_pkl,
entry=name)
if _version: # save the key
try: try:
key_data.save_pkl() key_data.add_key(key, save_pkl=bool(_version))
key_broken = False key_broken = False
except cPickle.PicklingError: except cPickle.PicklingError:
# This should only happen if we tried to save the
# pickled file.
assert _version
# The key we are trying to add is broken: we will not
# add it after all.
key_data.remove_key(key)
key_broken = True key_broken = True
# Remove key from the KeyData object, to make sure
# we never try to save it again.
# We still keep the KeyData object and save it so
# that the module can be re-used in the future.
key_data.keys = set()
key_data.save_pkl()
if not key_broken and self.check_for_broken_eq:
self.check_key(key, key_pkl)
# Adding the KeyData file to this set means it is a
# versioned module.
self.loaded_key_pkl.add(key_pkl)
# Map the new module to its KeyData object. Note that we if (_version and not key_broken and
# need to do it regardless of whether the key is versioned self.check_for_broken_eq):
# or not if we want to be able to re-use this module inside self.check_key(key, key_data.key_pkl)
# the same process.
self.module_hash_to_key_data[module_hash] = key_data
except: # We can delete the work directory.
# TODO try / except / finally is not Python2.4-friendly. _rmtree(location, ignore_nocleanup=True,
# This may happen e.g. when an Op has no C implementation. In msg='temporary workdir of duplicated module')
# any case, we do not want to keep around the temporary work
# directory, as it may cause trouble if we create too many of else:
# these. The 'ignore_if_missing' flag is set just in case this # Will fail if there is an error compiling the C code.
# directory would have already been deleted. # The exception will be caught and the work dir will be
_rmtree(location, ignore_if_missing=True, # deleted.
msg='exception -- typically means no C implementation') while True:
raise try:
# The module should be returned by the last
# step of the compilation.
module = compile_steps.next()
except StopIteration:
break
# Obtain path to the '.so' module file.
name = module.__file__
debug("Adding module to cache", key, name)
assert name.startswith(location)
assert name not in self.module_from_name
# Changing the hash of the key is not allowed during
# compilation. That is the only cause found that makes the
# following assert fail.
assert hash(key) == hash_key
assert key not in self.entry_from_key
key_pkl = os.path.join(location, 'key.pkl')
assert not os.path.exists(key_pkl)
key_data = KeyData(
keys=set([key]),
module_hash=module_hash,
key_pkl=key_pkl,
entry=name)
if _version: # save the key
try:
key_data.save_pkl()
key_broken = False
except cPickle.PicklingError:
key_broken = True
# Remove key from the KeyData object, to make sure
# we never try to save it again.
# We still keep the KeyData object and save it so
# that the module can be re-used in the future.
key_data.keys = set()
key_data.save_pkl()
if not key_broken and self.check_for_broken_eq:
self.check_key(key, key_pkl)
# Adding the KeyData file to this set means it is a
# versioned module.
self.loaded_key_pkl.add(key_pkl)
# Map the new module to its KeyData object. Note that we
# need to do it regardless of whether the key is versioned
# or not if we want to be able to re-use this module inside
# the same process.
self.module_hash_to_key_data[module_hash] = key_data
except:
# This may happen e.g. when an Op has no C implementation. In
# any case, we do not want to keep around the temporary work
# directory, as it may cause trouble if we create too many of
# these. The 'ignore_if_missing' flag is set just in case this
# directory would have already been deleted.
_rmtree(location, ignore_if_missing=True,
msg='exception -- typically means no C implementation')
raise
finally: finally:
# Release lock if needed. # Release lock if needed.
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论