Skip to content

Instantly share code, notes, and snippets.

@demianbrecht
Created January 14, 2015 16:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save demianbrecht/bc6530a40718e4fcbf90 to your computer and use it in GitHub Desktop.
Save demianbrecht/bc6530a40718e4fcbf90 to your computer and use it in GitHub Desktop.
Overriding stdlib http package
import sys
from importlib import invalidate_caches
from importlib.abc import MetaPathFinder
from importlib.machinery import ModuleSpec, SourceFileLoader
from os.path import dirname, join, abspath, isdir, isfile
class Finder(MetaPathFinder):
def find_spec(self, fullname, path, target=None):
name_parts = fullname.split('.')
if name_parts[0] != 'http':
# don't worry about non-http modules
return
name_parts[0] = 'httplib3'
find_path = abspath(join(*name_parts))
if isdir(find_path):
origin = join(find_path, '__init__.py')
else:
origin = '{}.py'.format(find_path)
if not isfile(origin):
# assume it's a module attribute
return
loader = SourceFileLoader(fullname, origin)
is_package = loader.is_package(fullname)
spec = ModuleSpec(
fullname, loader, is_package=is_package, origin=origin)
if is_package:
spec.submodule_search_locations = [dirname(__file__)]
return spec
def inject():
invalidate_caches()
for k in [k for k in sys.modules.keys() if k.startswith('http')]:
del sys.modules[k]
sys.meta_path.insert(0, Finder())
@mdengler
Copy link

Do you really want to delete all already-loaded modules that start with 'http'? How about just a whitelist of names and prefixes (if necessary)? If someone tries to use their "httputils" module they might be surprised. There are 58 distributions on pypi that start with "http":

$ curl -s 'https://pypi.python.org/pypi?%3Aaction=index' | grep pypi/http | wc
58

$ curl -s 'https://pypi.python.org/pypi?%3Aaction=index' | grep pypi/http | head -5
 <td><a href="/pypi/http/0.02">http&nbsp;0.02</a></td>
 <td><a href="/pypi/http1/0.3.1">http1&nbsp;0.3.1</a></td>
 <td><a href="/pypi/http2/0.0.0-dev">http2&nbsp;0.0.0-dev</a></td>
 <td><a href="/pypi/httpagentparser/1.7.6">httpagentparser&nbsp;1.7.6</a></td>
 <td><a href="/pypi/httpappengine/0.1.9">httpappengine&nbsp;0.1.9</a></td>

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