From d1df83ba6c2c7dfb6e792c46e3fccb2c1d2310cc Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Mon, 7 Mar 1994 11:45:36 +0000 Subject: urlopen: add basejoin() function. addpack: new module to add packages to sys.path. --- Lib/addpack.py | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++ Lib/lib-old/addpack.py | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++ Lib/urlopen.py | 22 +++++++++++++++++ 3 files changed, 156 insertions(+) create mode 100644 Lib/addpack.py create mode 100644 Lib/lib-old/addpack.py diff --git a/Lib/addpack.py b/Lib/addpack.py new file mode 100644 index 0000000..3d09236 --- /dev/null +++ b/Lib/addpack.py @@ -0,0 +1,67 @@ +# This module provides standard support for "packages". +# +# The idea is that large groups of related modules can be placed in +# their own subdirectory, which can be added to the Python search path +# in a relatively easy way. +# +# The current version takes a package name and searches the Python +# search path for a directory by that name, and if found adds it to +# the module search path (sys.path). It maintains a list of packages +# that have already been added so adding the same package many times +# is OK. +# +# It is intended to be used in a fairly stylized manner: each module +# that wants to use a particular package, say 'Foo', is supposed to +# contain the following code: +# +# from addpack import addpack +# addpack('Foo') +# +# +# Additional arguments, when present, provide additional places where +# to look for the package before trying sys.path (these may be either +# strings or lists/tuples of strings). Also, if the package name is a +# full pathname, first the last component is tried in the usual way, +# then the full pathname is tried last. If the package name is a +# *relative* pathname (UNIX: contains a slash but doesn't start with +# one), then nothing special is done. The packages "/foo/bar/bletch" +# and "bletch" are considered the same, but unrelated to "bar/bletch". +# +# If the algorithm finds more than one suitable subdirectory, all are +# added to the search path -- this makes it possible to override part +# of a package. The same path will not be added more than once. +# +# If no directory is found, ImportError is raised. + +_packs = {} # {pack: [pathname, ...], ...} + +def addpack(pack, *locations): + import os + if os.path.isabs(pack): + base = os.path.basename(pack) + else: + base = pack + if _packs.has_key(base): + return + import sys + path = [] + for loc in _flatten(locations) + sys.path: + fn = os.path.join(loc, base) + if fn not in path and os.path.isdir(fn): + path.append(fn) + if pack != base and pack not in path and os.path.isdir(pack): + path.append(pack) + if not path: raise ImportError, 'package ' + pack + ' not found' + _packs[base] = path + for fn in path: + if fn not in sys.path: + sys.path.append(fn) + +def _flatten(locations): + locs = [] + for loc in locations: + if type(loc) == type(''): + locs.append(loc) + else: + locs = locs + _flatten(loc) + return locs diff --git a/Lib/lib-old/addpack.py b/Lib/lib-old/addpack.py new file mode 100644 index 0000000..3d09236 --- /dev/null +++ b/Lib/lib-old/addpack.py @@ -0,0 +1,67 @@ +# This module provides standard support for "packages". +# +# The idea is that large groups of related modules can be placed in +# their own subdirectory, which can be added to the Python search path +# in a relatively easy way. +# +# The current version takes a package name and searches the Python +# search path for a directory by that name, and if found adds it to +# the module search path (sys.path). It maintains a list of packages +# that have already been added so adding the same package many times +# is OK. +# +# It is intended to be used in a fairly stylized manner: each module +# that wants to use a particular package, say 'Foo', is supposed to +# contain the following code: +# +# from addpack import addpack +# addpack('Foo') +# +# +# Additional arguments, when present, provide additional places where +# to look for the package before trying sys.path (these may be either +# strings or lists/tuples of strings). Also, if the package name is a +# full pathname, first the last component is tried in the usual way, +# then the full pathname is tried last. If the package name is a +# *relative* pathname (UNIX: contains a slash but doesn't start with +# one), then nothing special is done. The packages "/foo/bar/bletch" +# and "bletch" are considered the same, but unrelated to "bar/bletch". +# +# If the algorithm finds more than one suitable subdirectory, all are +# added to the search path -- this makes it possible to override part +# of a package. The same path will not be added more than once. +# +# If no directory is found, ImportError is raised. + +_packs = {} # {pack: [pathname, ...], ...} + +def addpack(pack, *locations): + import os + if os.path.isabs(pack): + base = os.path.basename(pack) + else: + base = pack + if _packs.has_key(base): + return + import sys + path = [] + for loc in _flatten(locations) + sys.path: + fn = os.path.join(loc, base) + if fn not in path and os.path.isdir(fn): + path.append(fn) + if pack != base and pack not in path and os.path.isdir(pack): + path.append(pack) + if not path: raise ImportError, 'package ' + pack + ' not found' + _packs[base] = path + for fn in path: + if fn not in sys.path: + sys.path.append(fn) + +def _flatten(locations): + locs = [] + for loc in locations: + if type(loc) == type(''): + locs.append(loc) + else: + locs = locs + _flatten(loc) + return locs diff --git a/Lib/urlopen.py b/Lib/urlopen.py index 47f0f20..c43b7f4 100755 --- a/Lib/urlopen.py +++ b/Lib/urlopen.py @@ -303,6 +303,28 @@ class addinfo(addbase): return self.headers +# Utility to combine a URL with a base URL to form a new URL + +def basejoin(base, url): + type, path = splittype(url) + if type: return url + host, path = splithost(path) + basetype, basepath = splittype(base) + basehost, basepath = splithost(basepath) + basepath, basetag = splittag(basepath) + basepath, basequery = splitquery(basepath) + type = basetype or 'file' + if path[:1] != '/': + import string + i = string.rfind(basepath, '/') + if i < 0: basepath = '/' + else: basepath = basepath[:i+1] + path = basepath + path + if not host: host = basehost + if host: return type + '://' + host + path + else: return type + ':' + path + + # Utilities to parse URLs: # unwrap('') --> 'type//host/path' # splittype('type:opaquestring') --> 'type', 'opaquestring' -- cgit v0.12