~ntt-pf-lab/nova/monkey_patch_notification

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/twisted/python/versions.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- test-case-name: twisted.python.test.test_versions -*-
 
2
# Copyright (c) 2006-2008 Twisted Matrix Laboratories.
 
3
# See LICENSE for details.
 
4
 
 
5
"""
 
6
Versions for Python packages.
 
7
 
 
8
See L{Version}.
 
9
"""
 
10
 
 
11
import sys, os
 
12
 
 
13
 
 
14
class _inf(object):
 
15
    """
 
16
    An object that is bigger than all other objects.
 
17
    """
 
18
    def __cmp__(self, other):
 
19
        """
 
20
        @param other: Another object.
 
21
        @type other: any
 
22
 
 
23
        @return: 0 if other is inf, 1 otherwise.
 
24
        @rtype: C{int}
 
25
        """
 
26
        if other is _inf:
 
27
            return 0
 
28
        return 1
 
29
 
 
30
_inf = _inf()
 
31
 
 
32
 
 
33
class IncomparableVersions(TypeError):
 
34
    """
 
35
    Two versions could not be compared.
 
36
    """
 
37
 
 
38
class Version(object):
 
39
    """
 
40
    An object that represents a three-part version number.
 
41
 
 
42
    If running from an svn checkout, include the revision number in
 
43
    the version string.
 
44
    """
 
45
    def __init__(self, package, major, minor, micro, prerelease=None):
 
46
        """
 
47
        @param package: Name of the package that this is a version of.
 
48
        @type package: C{str}
 
49
        @param major: The major version number.
 
50
        @type major: C{int}
 
51
        @param minor: The minor version number.
 
52
        @type minor: C{int}
 
53
        @param micro: The micro version number.
 
54
        @type micro: C{int}
 
55
        @param prerelease: The prerelease number.
 
56
        @type prerelease: C{int}
 
57
        """
 
58
        self.package = package
 
59
        self.major = major
 
60
        self.minor = minor
 
61
        self.micro = micro
 
62
        self.prerelease = prerelease
 
63
 
 
64
 
 
65
    def short(self):
 
66
        """
 
67
        Return a string in canonical short version format,
 
68
        <major>.<minor>.<micro>[+rSVNVer].
 
69
        """
 
70
        s = self.base()
 
71
        svnver = self._getSVNVersion()
 
72
        if svnver:
 
73
            s += '+r' + str(svnver)
 
74
        return s
 
75
 
 
76
 
 
77
    def base(self):
 
78
        """
 
79
        Like L{short}, but without the +rSVNVer.
 
80
        """
 
81
        if self.prerelease is None:
 
82
            pre = ""
 
83
        else:
 
84
            pre = "pre%s" % (self.prerelease,)
 
85
        return '%d.%d.%d%s' % (self.major,
 
86
                               self.minor,
 
87
                               self.micro,
 
88
                               pre)
 
89
 
 
90
 
 
91
    def __repr__(self):
 
92
        svnver = self._formatSVNVersion()
 
93
        if svnver:
 
94
            svnver = '  #' + svnver
 
95
        if self.prerelease is None:
 
96
            prerelease = ""
 
97
        else:
 
98
            prerelease = ", prerelease=%r" % (self.prerelease,)
 
99
        return '%s(%r, %d, %d, %d%s)%s' % (
 
100
            self.__class__.__name__,
 
101
            self.package,
 
102
            self.major,
 
103
            self.minor,
 
104
            self.micro,
 
105
            prerelease,
 
106
            svnver)
 
107
 
 
108
 
 
109
    def __str__(self):
 
110
        return '[%s, version %s]' % (
 
111
            self.package,
 
112
            self.short())
 
113
 
 
114
 
 
115
    def __cmp__(self, other):
 
116
        """
 
117
        Compare two versions, considering major versions, minor versions, micro
 
118
        versions, then prereleases.
 
119
 
 
120
        A version with a prerelease is always less than a version without a
 
121
        prerelease. If both versions have prereleases, they will be included in
 
122
        the comparison.
 
123
 
 
124
        @param other: Another version.
 
125
        @type other: L{Version}
 
126
 
 
127
        @return: NotImplemented when the other object is not a Version, or one
 
128
            of -1, 0, or 1.
 
129
 
 
130
        @raise IncomparableVersions: when the package names of the versions
 
131
            differ.
 
132
        """
 
133
        if not isinstance(other, self.__class__):
 
134
            return NotImplemented
 
135
        if self.package != other.package:
 
136
            raise IncomparableVersions("%r != %r"
 
137
                                       % (self.package, other.package))
 
138
 
 
139
        if self.prerelease is None:
 
140
            prerelease = _inf
 
141
        else:
 
142
            prerelease = self.prerelease
 
143
 
 
144
        if other.prerelease is None:
 
145
            otherpre = _inf
 
146
        else:
 
147
            otherpre = other.prerelease
 
148
 
 
149
        x = cmp((self.major,
 
150
                    self.minor,
 
151
                    self.micro,
 
152
                    prerelease),
 
153
                   (other.major,
 
154
                    other.minor,
 
155
                    other.micro,
 
156
                    otherpre))
 
157
        return x
 
158
 
 
159
 
 
160
    def _parseSVNEntries_4(self, entriesFile):
 
161
        """
 
162
        Given a readable file object which represents a .svn/entries file in
 
163
        format version 4, return the revision as a string.  We do this by
 
164
        reading first XML element in the document that has a 'revision'
 
165
        attribute.
 
166
        """
 
167
        from xml.dom.minidom import parse
 
168
        doc = parse(entriesFile).documentElement
 
169
        for node in doc.childNodes:
 
170
            if hasattr(node, 'getAttribute'):
 
171
                rev = node.getAttribute('revision')
 
172
                if rev is not None:
 
173
                    return rev.encode('ascii')
 
174
 
 
175
 
 
176
    def _parseSVNEntries_8(self, entriesFile):
 
177
        """
 
178
        Given a readable file object which represents a .svn/entries file in
 
179
        format version 8, return the revision as a string.
 
180
        """
 
181
        entriesFile.readline()
 
182
        entriesFile.readline()
 
183
        entriesFile.readline()
 
184
        return entriesFile.readline().strip()
 
185
    
 
186
    
 
187
    # Add handlers for version 9 and 10 formats, which are the same as
 
188
    # version 8 as far as revision information is concerned.
 
189
    _parseSVNEntries_9 = _parseSVNEntries_8
 
190
    _parseSVNEntriesTenPlus = _parseSVNEntries_8
 
191
 
 
192
 
 
193
    def _getSVNVersion(self):
 
194
        """
 
195
        Figure out the SVN revision number based on the existance of
 
196
        <package>/.svn/entries, and its contents. This requires discovering the
 
197
        format version from the 'format' file and parsing the entries file
 
198
        accordingly.
 
199
 
 
200
        @return: None or string containing SVN Revision number.
 
201
        """
 
202
        mod = sys.modules.get(self.package)
 
203
        if mod:
 
204
            svn = os.path.join(os.path.dirname(mod.__file__), '.svn')
 
205
            if not os.path.exists(svn):
 
206
                # It's not an svn working copy
 
207
                return None
 
208
 
 
209
            formatFile = os.path.join(svn, 'format')
 
210
            if os.path.exists(formatFile):
 
211
                # It looks like a less-than-version-10 working copy.
 
212
                format = file(formatFile).read().strip()
 
213
                parser = getattr(self, '_parseSVNEntries_' + format, None)
 
214
            else:
 
215
                # It looks like a version-10-or-greater working copy, which
 
216
                # has version information in the entries file.
 
217
                parser = self._parseSVNEntriesTenPlus
 
218
 
 
219
            if parser is None:
 
220
                return 'Unknown'
 
221
 
 
222
            entriesFile = os.path.join(svn, 'entries')
 
223
            entries = file(entriesFile)
 
224
            try:
 
225
                try:
 
226
                    return parser(entries)
 
227
                finally:
 
228
                    entries.close()
 
229
            except:
 
230
                return 'Unknown'
 
231
 
 
232
 
 
233
    def _formatSVNVersion(self):
 
234
        ver = self._getSVNVersion()
 
235
        if ver is None:
 
236
            return ''
 
237
        return ' (SVN r%s)' % (ver,)
 
238
 
 
239
 
 
240
 
 
241
def getVersionString(version):
 
242
    """
 
243
    Get a friendly string for the given version object.
 
244
 
 
245
    @param version: A L{Version} object.
 
246
    @return: A string containing the package and short version number.
 
247
    """
 
248
    result = '%s %s' % (version.package, version.short())
 
249
    return result