def test_goodSVNEntries_4(self): """ Version should be able to parse an SVN format 4 entries file. """ version = Version("dummy", 1, 0, 0) self.assertEqual( version._parseSVNEntries_4(BytesIO(VERSION_4_ENTRIES)), b'18211')
def test_goodSVNEntries_9(self): """ Version should be able to parse an SVN format 9 entries file. """ version = Version("dummy", 1, 0, 0) self.assertEqual( version._parseSVNEntries_9(StringIO(VERSION_9_ENTRIES)), '22715')
def test_goodSVNEntriesTenPlus(self): """ Version should be able to parse an SVN format 10 entries file. """ version = Version("dummy", 1, 0, 0) self.assertEqual( version._parseSVNEntriesTenPlus(BytesIO(VERSION_10_ENTRIES)), b'22715')
def test_notImplementedComparisons(self): """ Comparing a L{Version} to some other object type results in C{NotImplemented}. """ va = Version("dummy", 1, 0, 0) vb = ("dummy", 1, 0, 0) # a tuple is not a Version object self.assertEqual(va.__cmp__(vb), NotImplemented)
def test_parseBrokenSVNEntries(self): """ If there is a broken SVN entries file, it should return an SVN revision of "Unknown". """ version = Version("dummy", 1, 0, 0) self.assertEquals(version._parseSVNEntries(StringIO('I like puppies')), "Unknown")
def todo_relative_redirect(test_method): expected_version = Version('twisted', 13, 1, 0) if current_version < expected_version: test_method.todo = ( "Relative Redirects are not supported in Twisted versions " "prior to: {0}").format(expected_version.short()) return test_method
def getVersion(self): versions = [] pattern = 'twisted-%s-md5sums.txt' for md5sums in self.RELEASES.globChildren(pattern % '*'): try: components = map(int, md5sums.basename().split('-')[1].split('.')) except ValueError: pass else: versions.append(components) try: version = Version('Twisted', *max(versions)) except ValueError: self.log.error( "Could not parse a version from files in the RELEASES directory %s" % ( self.RELEASES.path,)) raise TracError("Error loading Twisted version information") md5sums_file = self.RELEASES.child(pattern % version.base()) return version, md5sums_file
def test_goodSVNEntries(self): """ Version should be able to parse an SVN entries file. """ version = Version("dummy", 1, 0, 0) crap = '''<?xml version="1.0" encoding="utf-8"?> <wc-entries xmlns="svn:"> <entry committed-rev="18210" name="" committed-date="2006-09-21T04:43:09.542953Z" url="svn+ssh://svn.twistedmatrix.com/svn/Twisted/trunk/twisted" last-author="exarkun" kind="dir" uuid="bbbe8e31-12d6-0310-92fd-ac37d47ddeeb" repos="svn+ssh://svn.twistedmatrix.com/svn/Twisted" revision="18211"/> </wc-entries> ''' self.assertEquals(version._parseSVNEntries(StringIO(crap)), '18211')
def __init__(self, keyObject): """ Initialize with a private or public C{cryptography.hazmat.primitives.asymmetric} key. @param keyObject: Low level key. @type keyObject: C{cryptography.hazmat.primitives.asymmetric} key. """ # Avoid importing PyCrypto if at all possible if keyObject.__class__.__module__.startswith('Crypto.PublicKey'): warningString = getDeprecationWarningString( Key, Version("Twisted", 16, 0, 0), replacement='passing a cryptography key object') warnings.warn(warningString, DeprecationWarning, stacklevel=2) self.keyObject = keyObject else: self._keyObject = keyObject
def test_deprecatedReplacementWithCallable(self): """ L{deprecated} takes an additional replacement parameter that can be used to indicate the new, non-deprecated method developers should use. If the replacement parameter is a callable, its fully qualified name will be interpolated into the warning message. """ version = Version('Twisted', 8, 0, 0) decorator = deprecated(version, replacement=dummyReplacementMethod) dummy = decorator(dummyCallable) self.assertEqual( dummy.__doc__, "\n" " Do nothing.\n\n" " This is used to test the deprecation decorators.\n\n" " Deprecated in Twisted 8.0.0; please use " "twisted.python.test.test_deprecate.dummyReplacementMethod" " instead.\n" " ")
def getNextVersion(version, now=None): """ Calculate the version number for a new release of Twisted based on the previous version number. @param version: The previous version number. @param now: (optional) The current date. """ # XXX: This has no way of incrementing the patch number. Currently, we # don't need it. See bug 2915. Jonathan Lange, 2007-11-20. if now is None: now = date.today() major = now.year - VERSION_OFFSET if major != version.major: minor = 0 else: minor = version.minor + 1 return Version(version.package, major, minor, 0)
def deprecatedWorkerModuleAttribute(scope, attribute, compat_name=None, new_name=None): """This is similar to Twisted's deprecatedModuleAttribute, but for Worker API Rename warnings. Can be used to create compatibility attributes for module-level classes, functions and global variables. :param scope: module scope (locals() in the context of a module) :param attribute: module object (class, function, global variable) :param compat_name: optional compatibility name (will be generated if not specified) :param new_name: optional new name (will be used name of attribute object in the module is not specified). If empty string is specified, then no new name is assumed for this attribute. """ module_name = scope["__name__"] assert module_name in sys.modules, "scope must be module, i.e. locals()" assert sys.modules[module_name].__dict__ is scope, \ "scope must be module, i.e. locals()" if new_name is None: scope_keys = list(scope.keys()) scope_values = list(scope.values()) attribute_name = scope_keys[scope_values.index(attribute)] else: attribute_name = new_name compat_name = _compat_name(attribute_name, compat_name=compat_name) scope[compat_name] = attribute if attribute_name: msg = "Use {0} instead.".format(attribute_name) else: msg = "Don't use it." _deprecatedModuleAttribute(Version("Buildbot", 0, 9, 0), _WORKER_WARNING_MARK + msg, module_name, compat_name)
def changeAllProjectVersions(root, versionTemplate): """ Change the version of all projects (including core and all subprojects). @type root: L{FilePath} @param root: The root of the Twisted source tree. @type versionTemplate: L{Version} @param versionTemplate: The version of all projects. The name will be replaced for each respective project. """ for project in findTwistedProjects(root): if project.directory.basename() == "twisted": packageName = "twisted" else: packageName = "twisted." + project.directory.basename() version = Version(packageName, versionTemplate.major, versionTemplate.minor, versionTemplate.micro, prerelease=versionTemplate.prerelease) project.updateVersion(version)
def test_deprecatedUpdatesDocstring(self): """ The docstring of the deprecated function is appended with information about the deprecation. """ def localDummyCallable(): """ Do nothing. This is used to test the deprecation decorators. """ version = Version('Twisted', 8, 0, 0) dummy = deprecated(version)(localDummyCallable) _appendToDocstring(localDummyCallable, _getDeprecationDocstring(version, '')) self.assertEqual(localDummyCallable.__doc__, dummy.__doc__)
def test_deprecateEmitsWarning(self): """ Decorating a callable with L{deprecated} emits a warning. """ version = Version('Twisted', 8, 0, 0) dummy = deprecated(version)(dummyCallable) def addStackLevel(): dummy() with catch_warnings(record=True) as caught: simplefilter("always") addStackLevel() self.assertEqual(caught[0].category, DeprecationWarning) self.assertEqual( str(caught[0].message), getDeprecationWarningString(dummyCallable, version)) # rstrip in case .pyc/.pyo self.assertEqual(caught[0].filename.rstrip('co'), __file__.rstrip('co'))
def test_verifyHostname_mismatching(self): """Check that ``verifyHostname()`` returns ``False`` when the ``SSLVerifyingContextFactory.hostname`` does not match the one found in the level 0 certificate subject CN. """ if _twistedversion >= Version('twisted', 14, 0, 0): raise unittest.SkipTest( ("The SSLVerifyingContextFactory is no longer necessary in " "Twisted>=14.0.0, because the way in which TLS certificates " "are checked now includes certificate pinning, and the " "SSLVerifyingContextFactory only implemented strict hostname " "checking.")) agent = txrecaptcha._getAgent(self.reactor, self.url) contextFactory = agent._contextFactory x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, self._certificateText) conn = DummyEndpoint() result = contextFactory.verifyHostname(conn, x509, 0, 0, True) self.assertIs(result, False)
def test_doSourceUnpack(self): """ C{doSourceUnpack} should execute a shell command which runs an untar command on the release tarball for the given projects. It should run each command in the dist directory of the corresponding project. """ project = Project(name="Foo", initPath=FilePath(self.mktemp()), version=Version("Foo", 1, 2, 3), package=None) doSourceUnpack([project], FilePath("/test/path"), False, sh=self.fakeShell, chdir=self.fakeChdir) self.assertEqual(self.commands, [ ("/test/path/Foo/dist", "tar xzf Foo-1.2.3.tar.gz", False, False) ])
class PropertyAccessor(object): """ A mixin class for Python 2.2 that uses AccessorType. This provides compatability with the pre-2.2 Accessor mixin, up to a point. Extending this class will give you explicit accessor methods; a method called set_foo, for example, is the same as an if statement in __setattr__ looking for 'foo'. Same for get_foo and del_foo. There are also reallyDel and reallySet methods, so you can override specifics in subclasses without clobbering __setattr__ and __getattr__, or using non-2.1 compatible code. There is are incompatibilities with Accessor - accessor methods added after class creation will *not* be detected. OTOH, this method is probably way faster. In addition, class attributes will only be used if no getter was defined, and instance attributes will not override getter methods whereas in original Accessor the class attribute or instance attribute would override the getter method. """ # addendum to above: # The behaviour of Accessor is wrong IMHO, and I've found bugs # caused by it. # -- itamar deprecatedModuleAttribute( Version("Twisted", 12, 1, 0), "PropertyAccessor is old and untested. Please write your own version " "of this functionality if you need it.", "twisted.python.reflect", "PropertyAccessor") __metaclass__ = AccessorType def reallySet(self, k, v): self.__dict__[k] = v def reallyDel(self, k): del self.__dict__[k]
def getNextVersion(version, prerelease, patch, today): """ Calculate the version number for a new release of Twisted based on the previous version number. @param version: The previous version number. @type prerelease: C{bool} @param prerelease: If C{True}, make the next version a pre-release one. If C{version} is a pre-release, it increments the pre-release counter, otherwise create a new version with prerelease set to 1. @type patch: C{bool} @param patch: If C{True}, make the next version a patch release. It increments the micro counter. @type today: C{datetime} @param today: The current date. """ micro = 0 major = today.year - VERSION_OFFSET if major != version.major: minor = 0 else: minor = version.minor + 1 if patch: micro = version.micro + 1 major = version.major minor = version.minor newPrerelease = None if version.prerelease is not None: major = version.major minor = version.minor micro = version.micro if prerelease: newPrerelease = version.prerelease + 1 elif prerelease: newPrerelease = 1 return Version(version.package, major, minor, micro, newPrerelease)
def test_nestedDeprecation(self): """ L{callDeprecated} ignores all deprecations apart from the first. Multiple warnings are generated when a deprecated function calls another deprecated function. The first warning is the one generated by the explicitly called function. That's the warning that we care about. """ differentVersion = Version('Foo', 1, 2, 3) def nestedDeprecation(*args): return oldMethod(*args) nestedDeprecation = deprecated(differentVersion)(nestedDeprecation) self.callDeprecated(differentVersion, nestedDeprecation, 24) # The oldMethod deprecation should have been emitted too, not captured # by callDeprecated. Flush it now to make sure it did happen and to # prevent it from showing up on stdout. warningsShown = self.flushWarnings() self.assertEqual(len(warningsShown), 1)
def test_makeTags(self): """ C{makeTags} should execute a shell command which creates a release tag of the given release branch for each given project. """ project = Project(name="Foo", initPath=self.mktemp(), version=Version("Foo", 1, 2, 3), package=None) makeTags([project], "Stuff", "svn+ssh://divmod.org/svn/Stuff/branches/release-1", False, sh=self.fakeShell) self.assertEqual( self.commands, [(None, "svn cp svn+ssh://divmod.org/svn/Stuff/branches/release-1/Foo " "svn+ssh://divmod.org/svn/Stuff/tags/releases/Foo-1.2.3 " '-m "Tagging release"', False, False)])
class SSLContextFactory: """ An SSL Context Factory. This loads a certificate and private key from a specified file. """ deprecatedModuleAttribute( Version("Twisted", 12, 2, 0), "Use twisted.internet.ssl.DefaultOpenSSLContextFactory instead.", "twisted.mail.protocols", "SSLContextFactory") def __init__(self, filename): self.filename = filename def getContext(self): """Create an SSL context.""" from OpenSSL import SSL ctx = SSL.Context(SSL.SSLv23_METHOD) ctx.use_certificate_file(self.filename) ctx.use_privatekey_file(self.filename) return ctx
def test_doInstall(self): """ C{doInstall} should execute a shell command which runs the I{install} subcommand of the I{setup.py} for each project given. It should run each command in the unpacked source directory of each project. """ project = Project(name="Foo", initPath=FilePath(self.mktemp()), version=Version("Foo", 1, 2, 3), package=None) installedPath = doInstall([project], FilePath("/test/path"), False, sh=self.fakeShell, chdir=self.fakeChdir) self.assertEqual(self.commands, [ ("/test/path/Foo/dist/Foo-1.2.3", executable + " setup.py install --prefix " + installedPath.path, False, False) ])
class Settable: """ A mixin class for syntactic sugar. Lets you assign attributes by calling with keyword arguments; for example, C{x(a=b,c=d,y=z)} is the same as C{x.a=b;x.c=d;x.y=z}. The most useful place for this is where you don't want to name a variable, but you do want to set some attributes; for example, C{X()(y=z,a=b)}. """ deprecatedModuleAttribute( Version("Twisted", 12, 1, 0), "Settable is old and untested. Please write your own version of this " "functionality if you need it.", "twisted.python.reflect", "Settable") def __init__(self, **kw): self(**kw) def __call__(self, **kw): for key, val in kw.items(): setattr(self, key, val) return self
def test_not_catched_warning(self): buildbot_module = new.module('buildbot_module') buildbot_module.deprecated_attr = 1 with mock.patch.dict(sys.modules, {'buildbot_module': buildbot_module}): deprecatedModuleAttribute(Version("Buildbot", 0, 9, 0), "test message", "buildbot_module", "deprecated_attr") # Overwrite with Twisted's module wrapper. import buildbot_module warnings = self.flushWarnings([self.test_not_catched_warning]) self.assertEqual(len(warnings), 0) # Should produce warning buildbot_module.deprecated_attr warnings = self.flushWarnings([self.test_not_catched_warning]) self.assertEqual(len(warnings), 1) self.assertEqual(warnings[0]['category'], DeprecationWarning) self.assertIn("test message", warnings[0]['message'])
def test_collectTarballs(self): """ C{collectTarballs} should move the release tarball for each given project into a directory named I{releases} of the current working directory. """ moves = [] class FakeFilePath(FilePath): def moveTo(self, target): moves.append((self, target)) FakeFilePath.clonePath = FakeFilePath project = Project(name="Foo", initPath=FakeFilePath(self.mktemp()), version=Version("Foo", 1, 2, 3), package=None) releasePath = FilePath(self.mktemp()) collectTarballs([project], FakeFilePath("/test/path"), releasePath) self.assertEqual( moves, [(FilePath('/test/path/Foo/dist/Foo-1.2.3.tar.gz'), releasePath.child('releases').child('Foo-1.2.3.tar.gz'))])
class DryRunVisitor(object): """ A visitor that makes a reporter think that every test visited has run successfully. """ deprecatedModuleAttribute(Version("Twisted", 13, 0, 0), "Trial no longer has support for visitors", "twisted.trial.runner", "DryRunVisitor") def __init__(self, reporter): """ @param reporter: A C{TestResult} object. """ self.reporter = reporter def markSuccessful(self, testCase): """ Convince the reporter that this test has been run successfully. """ self.reporter.startTest(testCase) self.reporter.addSuccess(testCase) self.reporter.stopTest(testCase)
class ClassWithDeprecatedProperty(object): """ Class with a single deprecated property. """ _someProtectedValue = None @deprecatedProperty(Version('Twisted', 1, 2, 3)) def someProperty(self): """ Getter docstring. @return: The property. """ return self._someProtectedValue @someProperty.setter def someProperty(self, value): """ Setter docstring. """ self._someProtectedValue = value
def main(self, args): """ Given a list of command-line arguments, change all the Twisted versions in the current directory. @type args: list of str @param args: List of command line arguments. This should only contain the version number. """ version_format = ( "Version should be in a form kind of like '1.2.3[pre4]'") if len(args) != 1: sys.exit("Must specify exactly one argument to change-versions") version = args[0] try: major, minor, micro_and_pre = version.split(".") except ValueError: raise SystemExit(version_format) if "pre" in micro_and_pre: micro, pre = micro_and_pre.split("pre") else: micro = micro_and_pre pre = None try: major = int(major) minor = int(minor) micro = int(micro) if pre is not None: pre = int(pre) except ValueError: raise SystemExit(version_format) version_template = Version("Whatever", major, minor, micro, prerelease=pre) self.changeAllProjectVersions(FilePath("."), version_template)
def test_asyncdef_asyncio(self): if twisted_version < Version('twisted', 18, 4, 0): raise SkipTest( 'Due to https://twistedmatrix.com/trac/ticket/9390, this test ' 'hangs when using Twisted versions lower than 18.4.0') resp = Response('http://example.com/index.html') class CoroMiddleware: async def process_request(self, request, spider): await asyncio.sleep(0.1) result = await get_from_asyncio_queue(resp) return result self.mwman._add_middleware(CoroMiddleware()) req = Request('http://example.com/index.html') download_func = mock.MagicMock() dfd = self.mwman.download(download_func, req, self.spider) results = [] dfd.addBoth(results.append) self._wait(dfd) self.assertIs(results[0], resp) self.assertFalse(download_func.called)
def _getAgent(reactor=reactor, url=API_SSL_VERIFY_URL, connectTimeout=30, **kwargs): """Create a :api:`twisted.web.client.Agent` which will verify the certificate chain and hostname for the given **url**. :param reactor: A provider of the :api:`twisted.internet.interface.IReactorTCP` interface. :param str url: The full URL which will be requested with the ``Agent``. (default: :attr:`API_SSL_VERIFY_URL`) :param pool: An :api:`twisted.web.client.HTTPConnectionPool` instance. (default: :attr:`_pool`) :type connectTimeout: None or int :param connectTimeout: If not ``None``, the timeout passed to :api:`twisted.internet.reactor.connectTCP` or :api:`twisted.internet.reactor.connectSSL` for specifying the connection timeout. (default: ``30``) """ # Twisted>=14.0.0 changed the way in which hostname verification works. if _twistedversion >= Version('twisted', 14, 0, 0): contextFactory = RecaptchaPolicyForHTTPS() else: contextFactory = SSLVerifyingContextFactory(url) if _connectionPoolAvailable: return client.Agent(reactor, contextFactory=contextFactory, connectTimeout=connectTimeout, pool=_pool, **kwargs) else: return client.Agent(reactor, contextFactory=contextFactory, connectTimeout=connectTimeout, **kwargs)
else: default = 80 if port == default: hostHeader = host else: hostHeader = host + b":" + intToBytes(port) self.requestHeaders.addRawHeader(b"host", hostHeader) def getClient(self): """ Get the client's IP address, if it has one. @return: The same value as C{getClientIP}. @rtype: L{bytes} """ return self.getClientIP() def redirect(self, url): """ Utility function that does a redirect. The request should have finish() called after this. """ self.setResponseCode(FOUND) self.setHeader(b"location", url) DummyRequest.getClient = deprecated(Version("Twisted", 15, 0, 0), "Twisted Names to resolve hostnames")( DummyRequest.getClient)
from binascii import hexlify, unhexlify from twisted.trial import unittest from twisted.python.compat import nativeString, networkString from twisted.python import components from twisted.python.versions import Version from twisted.internet import defer from twisted.cred import checkers, credentials, portal, error try: from crypt import crypt except ImportError: crypt = None # type: ignore[assignment,misc] # The Twisted version in which UsernameHashedPassword is first deprecated. _uhpVersion = Version("Twisted", "NEXT", 0, 0) class ITestable(Interface): """ An interface for a theoretical protocol. """ pass class TestAvatar: """ A test avatar. """ def __init__(self, name):
@param x: a string of type C{unicode} @param encoding: an optional codec, default: 'utf-8' @return: a string of type C{str} """ if isinstance(x, text_type) and not PY3: # On Python 2 and lower, type(u"") != type("") # so we need to encode() to return a native string. return x.encode(encoding, errors) return x _hush_pyflakes = [json] deprecatedModuleAttribute( Version("buildbot", 0, 9, 4), message="Use json from the standard library instead.", moduleName="buildbot.util", name="json", ) def toJson(obj): if isinstance(obj, datetime.datetime): return datetime2epoch(obj) # changes and schedulers consider None to be a legitimate name for a branch, # which makes default function keyword arguments hard to handle. This value # is always false.
# Copyright (c) Twisted Matrix Laboratories. # See LICENSE for details. """ Twisted's unit tests. """ from twisted.python.deprecate import deprecatedModuleAttribute from twisted.python.versions import Version from twisted.test import proto_helpers for obj in proto_helpers.__all__: deprecatedModuleAttribute( Version('Twisted', 19, 7, 0), 'Please use twisted.internet.testing.{} instead.'.format(obj), 'twisted.test.proto_helpers', obj)
if _PY3: # cgi.escape is deprecated in Python 3. from html import escape else: from cgi import escape NOT_DONE_YET = 1 __all__ = [ 'supportedMethods', 'Request', 'Session', 'Site', 'version', 'NOT_DONE_YET', 'GzipEncoderFactory' ] # backwards compatability deprecatedModuleAttribute( Version("Twisted", 12, 1, 0), "Please use twisted.web.http.datetimeToString instead", "twisted.web.server", "date_time_string") deprecatedModuleAttribute( Version("Twisted", 12, 1, 0), "Please use twisted.web.http.stringToDatetime instead", "twisted.web.server", "string_date_time") date_time_string = http.datetimeToString string_date_time = http.stringToDatetime # Support for other methods may be implemented on a per-resource basis. supportedMethods = ('GET', 'HEAD', 'POST') def _addressToTuple(addr): if isinstance(addr, address.IPv4Address): return ('INET', addr.host, addr.port)
@return: a bound method @rtype: L{types.MethodType} """ func = cls.__dict__[name] if _PY3: return _MethodType(func, self) return _MethodType(func, self, cls) from twisted.python.versions import Version from twisted.python.deprecate import deprecatedModuleAttribute from collections import OrderedDict deprecatedModuleAttribute(Version("Twisted", 15, 5, 0), "Use collections.OrderedDict instead.", "twisted.python.compat", "OrderedDict") if _PY3: from base64 import encodebytes as _b64encodebytes from base64 import decodebytes as _b64decodebytes else: from base64 import encodestring as _b64encodebytes from base64 import decodestring as _b64decodebytes def _bytesChr(i): """ Like L{chr} but always works on ASCII, returning L{bytes}. @param i: The ASCII code point to return.
class AppVersion(Entity): """Track application versions""" implements(IDroneModelAppVersion) description = property( lambda self: "%s %s" % \ (self.app.name, self.version_string) ) serializable = True def __getattribute__(self, name): """Overrode to fulfill Interface Obligations""" if name in ('package','major','minor','micro','prerelease','base',\ 'short'): return self.version.__getattribute__(name) return object.__getattribute__(self, name) def __init__(self, *args, **kwargs): self.version = Version(*args, **kwargs) self.app = IDroneModelApp(self.version) @property def version_string(self): """makes a nice version string that we can use for reconstruction""" result = '.'.join([ str(self.major), str(self.minor), str(self.micro), ]) if self.prerelease: result += '.%s' % str(self.prerelease) return result def __getstate__(self): return { 'app' : self.package, 'version' : self.version_string, #for proper serialization } def __cmp__(self, other): """overrode for easy comparison of AppVersion to AppVersion and Version to AppVersion. @raise IncomparableVersions: when the package names of the versions differ. @param other L{twisted.python.versions.Version}, L{IDroneModelAppVersion}, or object @return C{int} of value -1, 0, or 1 """ try: if IDroneModelAppVersion.providedBy(other): return self.version.__cmp__(other.version) except IncomparableVersions: raise except: pass if isinstance(other, Version): return self.version.__cmp__(other) return object.__cmp__(self, other) @staticmethod def makeAppVersion(name, version): """Similar to ``makeArgs`` @return L{IDroneModelAppVersion} provider """ args, kwargs = AppVersion.makeArgs(name, version) return AppVersion(*args, **kwargs) @staticmethod def makeVersion(name, version): """Similar to ``makeArgs`` @return L{twisted.python.versions.Version} """ args, kwargs = AppVersion.makeArgs(name, version) return Version(*args, **kwargs) @staticmethod def versionExists(name, version): """check if this L{IDroneModelAppVersion} provider exists""" args, kwargs = AppVersion.makeArgs(name, version) return AppVersion.exists(*args, **kwargs) @staticmethod def makeArgs(name, version): """goes through great lengths to make args for use by a constructor for class types - L{IDroneModelAppVersion} providers or L{twisted.python.versions.Version}. @raises TypeError - if version is not convertable @param name C{str} @param version C{str}, C{list}, C{tuple}, or L{twisted.python.versions.Version} @return ((name, major, minor, micro), {'prerelease': prerelease}) """ default = [0,0,0,0] #last number denotes pre-release if isinstance(version, Version): if version.package == name: return ( (name, version.major, version.minor, version.micro), {'prerelease': version.prerelease} ) else: version = [] if isinstance(version, str): version = version.split('.') elif isinstance(version, tuple): version = list(version) elif isinstance(version, type(None)): version = [] else: raise TypeError('Unacceptable version input %s' % type(version)) version = version + default #pad the length for comparisons v = [ i[0] for i in zip(version, default) ] kwargs = {'prerelease': None} try: #don't try too hard to get this right if len(v) == 4 and v[3]: kwargs['prerelease'] = int(v[3]) except: pass return (tuple((name,) + tuple([int(i) for i in v[0:3]])), kwargs) @staticmethod def construct(state): name = state['app'] appversion = AppVersion.makeAppVersion(name, state['version']) return appversion
] yield self.addCompleteLog('property changes', "\n".join(props_set)) if len(property_changes) > 1: self.descriptionDone = '{} properties set'.format( len(property_changes)) elif len(property_changes) == 1: self.descriptionDone = 'property \'{}\' set'.format( list(property_changes)[0]) if cmd.didFail(): return FAILURE return SUCCESS SetProperty = SetPropertyFromCommand deprecatedModuleAttribute(Version("Buildbot", 0, 8, 8), "It has been renamed to SetPropertyFromCommand", "buildbot.steps.shell", "SetProperty") class ShellCommandNewStyle(buildstep.ShellMixin, buildstep.BuildStep): # This is a temporary class until old ShellCommand is retired def __init__(self, **kwargs): if self.__class__ is ShellCommandNewStyle: if 'command' not in kwargs: config.error( "ShellCommandNewStyle's `command' argument is not specified" ) # check validity of arguments being passed to RemoteShellCommand
def __init__(self, *args, **kwargs): self.version = Version(*args, **kwargs) self.app = IDroneModelApp(self.version)