Source code for original

"""
Import hook extending pytz package with usable, generic timezones:
GMT-14 up to GMT+12.
 
Note that pytz already has Etc/GMT+X timezones, but
(quoting Wikipedia):
 
"In order to conform with the POSIX style, those zones beginning with "Etc/GMT"
have their sign reversed from what most people expect. In this style,
zones west of GMT have a positive sign and those east have a negative sign."
 
Because this is insane, we are simply introducing our own zones
that will not have this fatal flaw.

Alternatively one might prepend ti the __path__ attribute of a
module
"""
# Note: I setup DEBUG to hide the verbose output when one uses
# the module. This was used for testing the module and finding
# issues and will still be used as such. For day to day use it
# is presently disabled.
import os
import sys
import imp
from pprint import pprint

DEBUG = False

[docs]class OverlayImporter(object): # PEP302 prescribes the use of two different classes, finder # and loader, for finding and loading modules respectively. # Each class respectively provides a single method, find_module # and load_module. def __init__(self, *args, **kvps): if DEBUG : print("New Instance") self.mask = "_{}_" self.trap = None
[docs] def mapTarget(self, name) : return self.mask.format(name)
[docs] def mapSource(self, name) : mask = self.mask.split("{}") return name[len(mask[0]):-len(mask[-1])]
[docs] def rename(self, name) : # Currently this assumes the module is one level deep within # the package, that is the following structure is expcted # # package\ The folder containing the __init__.py you are reading # _module_ The module you are patching renamed with underscores # return ".".join([item if enum!=1 else "_{}_".format(item) for enum, item in enumerate(name.split('.'))])
[docs] def overlays(self) : # This is simply the list of modules that are patched under # this overlay. modules = [os.path.splitext(item)[0] for item in os.listdir(__path__[0]) if os.path.splitext(item)[0] not in ["__init__","__pycache__"]] if self.trap : return [self.mapSource(os.path.splitext(item)[0]) for item in modules] else : return modules
[docs] def find_module(self, name, path=None): # Deprecated use : # # Python > 3.3 use IMPORTLIB.UTIL.FIND_SPEC # Python = 3.3 use IMPORTLIB.FIND_LOADER # bits = name.split('.') if DEBUG : print("Searching > {1:<40} {0:<40}".format(name, str(path))) if len(bits) > 1 and self.mapTarget(bits[-1]) in self.overlays(): # Note : the clamp on bit length is to ensure the importer rolls back to root to import patched modules. self.path = path if DEBUG : print("Discovered : {}".format(name)) return self if bits[-1] == self.trap : for meta in sys.meta_path : if meta is not self : self.temp = meta.find_module(name, path) if self.temp : if DEBUG : print("Discovered : {}".format(name)) return self return None
[docs] def load_module(self, name): # Deprecated replace with the classes in IMPORTLIB.MACHINERY # # If IMP.LOAD_MODULE was used with IMP.FIND_MODULE previously # then IMPORTLIB.IMPORT_MODULE is a better substitute. If not # then use the loader that pairs with the prior finder. That # is one of : # # IMPORTLIB.UTIL.FIND_SPEC <-> # IMPORTLIB.FIND_LOADER <-> # if DEBUG : print("Importing > {}".format(name)) parent, _, module = name.rpartition('.') if self.trap : self.trap = None if DEBUG : print("Pass Trapped") temp = self.temp.load_module() sys.modules[self.mapTarget(name)] = temp if DEBUG : print("Imported < {}".format(self.mapTarget(name))) return temp else : if DEBUG : print("Pass Through") # if module not in self.overlays(): # Not Importable # raise ImportError("%s can only be used to import pytz!",self.__class__.__name__) # Inclde module name and possibly modules if name in sys.modules: # Already Imported return sys.modules[name] # Modules' absolute path self.trap = module file, path, desc = imp.find_module(self.mapTarget(module), self.path) # NB !!! This was psuedo try: temp = imp.load_module(name, file, path, desc) finally: if file: file.close() sys.modules[module] = temp if DEBUG : print("Imported < {}".format(module)) return temp
sys.meta_path.insert(0,OverlayImporter())