Commit 48dd1efa authored by PJ Eby's avatar PJ Eby

Added ``Distribution.clone()`` method, and keyword argument support to

other ``Distribution`` constructors.  Added the ``DEVELOP_DIST``
precedence, and automatically assign it to eggs using ``.egg-info``
format.

--HG--
branch : setuptools
extra : convert_revision : svn%3A6015fed2-1504-0410-9fe1-9d1591cc4771/sandbox/trunk/setuptools%4042259
parent e6577a41
...@@ -67,7 +67,7 @@ __all__ = [ ...@@ -67,7 +67,7 @@ __all__ = [
'ensure_directory', 'normalize_path', 'ensure_directory', 'normalize_path',
# Distribution "precedence" constants # Distribution "precedence" constants
'EGG_DIST', 'BINARY_DIST', 'SOURCE_DIST', 'CHECKOUT_DIST', 'EGG_DIST', 'BINARY_DIST', 'SOURCE_DIST', 'CHECKOUT_DIST', 'DEVELOP_DIST',
# "Provider" interfaces, implementations, and registration/lookup APIs # "Provider" interfaces, implementations, and registration/lookup APIs
'IMetadataProvider', 'IResourceProvider', 'FileMetadata', 'IMetadataProvider', 'IResourceProvider', 'FileMetadata',
...@@ -94,11 +94,11 @@ class UnknownExtra(ResolutionError): ...@@ -94,11 +94,11 @@ class UnknownExtra(ResolutionError):
_provider_factories = {} _provider_factories = {}
PY_MAJOR = sys.version[:3] PY_MAJOR = sys.version[:3]
EGG_DIST = 3 EGG_DIST = 3
BINARY_DIST = 2 BINARY_DIST = 2
SOURCE_DIST = 1 SOURCE_DIST = 1
CHECKOUT_DIST = 0 CHECKOUT_DIST = 0
DEVELOP_DIST = -1
def register_loader_type(loader_type, provider_factory): def register_loader_type(loader_type, provider_factory):
"""Register `provider_factory` to make providers for `loader_type` """Register `provider_factory` to make providers for `loader_type`
...@@ -1378,8 +1378,9 @@ def find_on_path(importer, path_item, only=False): ...@@ -1378,8 +1378,9 @@ def find_on_path(importer, path_item, only=False):
metadata = PathMetadata(path_item, fullpath) metadata = PathMetadata(path_item, fullpath)
else: else:
metadata = FileMetadata(fullpath) metadata = FileMetadata(fullpath)
yield Distribution.from_location(path_item,entry,metadata) yield Distribution.from_location(
path_item,entry,metadata,precedence=DEVELOP_DIST
)
elif not only and lower.endswith('.egg'): elif not only and lower.endswith('.egg'):
for dist in find_distributions(os.path.join(path_item, entry)): for dist in find_distributions(os.path.join(path_item, entry)):
yield dist yield dist
...@@ -1391,7 +1392,6 @@ def find_on_path(importer, path_item, only=False): ...@@ -1391,7 +1392,6 @@ def find_on_path(importer, path_item, only=False):
register_finder(ImpWrapper,find_on_path) register_finder(ImpWrapper,find_on_path)
_namespace_handlers = {} _namespace_handlers = {}
_namespace_packages = {} _namespace_packages = {}
...@@ -1736,7 +1736,7 @@ class Distribution(object): ...@@ -1736,7 +1736,7 @@ class Distribution(object):
self._provider = metadata or empty_provider self._provider = metadata or empty_provider
#@classmethod #@classmethod
def from_location(cls,location,basename,metadata=None): def from_location(cls,location,basename,metadata=None,**kw):
project_name, version, py_version, platform = [None]*4 project_name, version, py_version, platform = [None]*4
basename, ext = os.path.splitext(basename) basename, ext = os.path.splitext(basename)
if ext.lower() in (".egg",".egg-info"): if ext.lower() in (".egg",".egg-info"):
...@@ -1747,7 +1747,7 @@ class Distribution(object): ...@@ -1747,7 +1747,7 @@ class Distribution(object):
) )
return cls( return cls(
location, metadata, project_name=project_name, version=version, location, metadata, project_name=project_name, version=version,
py_version=py_version, platform=platform py_version=py_version, platform=platform, **kw
) )
from_location = classmethod(from_location) from_location = classmethod(from_location)
...@@ -1852,7 +1852,6 @@ class Distribution(object): ...@@ -1852,7 +1852,6 @@ class Distribution(object):
if self.platform: if self.platform:
filename += '-'+self.platform filename += '-'+self.platform
return filename return filename
def __repr__(self): def __repr__(self):
...@@ -1874,9 +1873,10 @@ class Distribution(object): ...@@ -1874,9 +1873,10 @@ class Distribution(object):
return getattr(self._provider, attr) return getattr(self._provider, attr)
#@classmethod #@classmethod
def from_filename(cls,filename,metadata=None): def from_filename(cls,filename,metadata=None, **kw):
return cls.from_location( return cls.from_location(
_normalize_cached(filename), os.path.basename(filename), metadata _normalize_cached(filename), os.path.basename(filename), metadata,
**kw
) )
from_filename = classmethod(from_filename) from_filename = classmethod(from_filename)
...@@ -1953,6 +1953,19 @@ class Distribution(object): ...@@ -1953,6 +1953,19 @@ class Distribution(object):
return False return False
return True return True
def clone(self,**kw):
"""Copy this distribution, substituting in any changed keyword args"""
for attr in (
'project_name', 'version', 'py_version', 'platform', 'location',
'precedence'
):
kw.setdefault(attr, getattr(self,attr,None))
kw.setdefault('metadata', self._provider)
return self.__class__(**kw)
def issue_warning(*args,**kw): def issue_warning(*args,**kw):
level = 1 level = 1
g = globals() g = globals()
...@@ -1966,6 +1979,34 @@ def issue_warning(*args,**kw): ...@@ -1966,6 +1979,34 @@ def issue_warning(*args,**kw):
from warnings import warn from warnings import warn
warn(stacklevel = level+1, *args, **kw) warn(stacklevel = level+1, *args, **kw)
def parse_requirements(strs): def parse_requirements(strs):
"""Yield ``Requirement`` objects for each specification in `strs` """Yield ``Requirement`` objects for each specification in `strs`
......
...@@ -754,20 +754,23 @@ If it is None, an ``EmptyProvider`` is used instead. ``Distribution`` objects ...@@ -754,20 +754,23 @@ If it is None, an ``EmptyProvider`` is used instead. ``Distribution`` objects
implement both the `IResourceProvider`_ and `IMetadataProvider Methods`_ by implement both the `IResourceProvider`_ and `IMetadataProvider Methods`_ by
delegating them to the `metadata` object. delegating them to the `metadata` object.
``Distribution.from_location(location, basename, metadata=None)`` (classmethod) ``Distribution.from_location(location, basename, metadata=None, **kw)`` (classmethod)
Create a distribution for `location`, which must be a string such as a Create a distribution for `location`, which must be a string such as a
URL, filename, or other string that might be used on ``sys.path``. URL, filename, or other string that might be used on ``sys.path``.
`basename` is a string naming the distribution, like ``Foo-1.2-py2.4.egg``. `basename` is a string naming the distribution, like ``Foo-1.2-py2.4.egg``.
If `basename` ends with ``.egg``, then the project's name, version, python If `basename` ends with ``.egg``, then the project's name, version, python
version and platform are extracted from the filename and used to set those version and platform are extracted from the filename and used to set those
properties of the created distribution. properties of the created distribution. Any additional keyword arguments
are forwarded to the ``Distribution()`` constructor.
``Distribution.from_filename(filename, metadata=None)`` (classmethod) ``Distribution.from_filename(filename, metadata=None**kw)`` (classmethod)
Create a distribution by parsing a local filename. This is a shorter way Create a distribution by parsing a local filename. This is a shorter way
of saying ``Distribution.from_location(normalize_path(filename), of saying ``Distribution.from_location(normalize_path(filename),
os.path.basename(filename), metadata)``. In other words, it creates a os.path.basename(filename), metadata)``. In other words, it creates a
distribution whose location is the normalize form of the filename, parsing distribution whose location is the normalize form of the filename, parsing
name and version information from the base portion of the filename. name and version information from the base portion of the filename. Any
additional keyword arguments are forwarded to the ``Distribution()``
constructor.
``Distribution(location,metadata,project_name,version,py_version,platform,precedence)`` ``Distribution(location,metadata,project_name,version,py_version,platform,precedence)``
Create a distribution by setting its properties. All arguments are Create a distribution by setting its properties. All arguments are
...@@ -834,10 +837,12 @@ precedence ...@@ -834,10 +837,12 @@ precedence
``parsed_version``. The default precedence is ``pkg_resources.EGG_DIST``, ``parsed_version``. The default precedence is ``pkg_resources.EGG_DIST``,
which is the highest (i.e. most preferred) precedence. The full list which is the highest (i.e. most preferred) precedence. The full list
of predefined precedences, from most preferred to least preferred, is: of predefined precedences, from most preferred to least preferred, is:
``EGG_DIST``, ``BINARY_DIST``, ``SOURCE_DIST``, and ``CHECKOUT_DIST``. ``EGG_DIST``, ``BINARY_DIST``, ``SOURCE_DIST``, ``CHECKOUT_DIST``, and
Normally, precedences other than ``EGG_DIST`` are used only by the ``DEVELOP_DIST``. Normally, precedences other than ``EGG_DIST`` are used
``setuptools.package_index`` module, when sorting distributions found in a only by the ``setuptools.package_index`` module, when sorting distributions
package index to determine their suitability for installation. found in a package index to determine their suitability for installation.
"System" and "Development" eggs (i.e., ones that use the ``.egg-info``
format), however, are automatically given a precedence of ``DEVELOP_DIST``.
...@@ -871,6 +876,11 @@ precedence ...@@ -871,6 +876,11 @@ precedence
of "extras" defined by the distribution, and the list returned will then of "extras" defined by the distribution, and the list returned will then
include any dependencies needed to support the named "extras". include any dependencies needed to support the named "extras".
``clone(**kw)``
Create a copy of the distribution. Any supplied keyword arguments override
the corresponding argument to the ``Distribution()`` constructor, allowing
you to change some of the copied distribution's attributes.
``egg_name()`` ``egg_name()``
Return what this distribution's standard filename should be, not including Return what this distribution's standard filename should be, not including
the ".egg" extension. For example, a distribution for project "Foo" the ".egg" extension. For example, a distribution for project "Foo"
...@@ -1524,6 +1534,12 @@ Release Notes/Change History ...@@ -1524,6 +1534,12 @@ Release Notes/Change History
versions for safe use in constructing egg filenames from a Distribution versions for safe use in constructing egg filenames from a Distribution
object's metadata. object's metadata.
* Added ``Distribution.clone()`` method, and keyword argument support to other
``Distribution`` constructors.
* Added the ``DEVELOP_DIST`` precedence, and automatically assign it to
eggs using ``.egg-info`` format.
0.6a9 0.6a9
* Don't raise an error when an invalid (unfinished) distribution is found * Don't raise an error when an invalid (unfinished) distribution is found
unless absolutely necessary. Warn about skipping invalid/unfinished eggs unless absolutely necessary. Warn about skipping invalid/unfinished eggs
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment