mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	
		
			
	
	
		
			68 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			68 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
|   | # 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') | ||
|  | #   <import modules from package 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 |