From 2b57d254787888aa292b15d7524cce444f0222cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Sun, 6 Oct 2024 19:20:04 +0200 Subject: [PATCH] buildbot.interfaces: add types --- master/buildbot/interfaces.py | 99 ++++++++++++++++++++++++----------- 1 file changed, 67 insertions(+), 32 deletions(-) diff --git a/master/buildbot/interfaces.py b/master/buildbot/interfaces.py index dcfa7e127831..939124e5eed7 100644 --- a/master/buildbot/interfaces.py +++ b/master/buildbot/interfaces.py @@ -23,9 +23,24 @@ # pylint: disable=no-method-argument # pylint: disable=inherit-non-class +from typing import TYPE_CHECKING +from typing import Any +from typing import Dict +from typing import List + from zope.interface import Attribute from zope.interface import Interface +if TYPE_CHECKING: + from twisted.internet.defer import Deferred + + from buildbot.config.master import MasterConfig + from buildbot.process.build import Build + from buildbot.process.log import Log + from buildbot.process.properties import Properties + from buildbot.process.workerforbuilder import LatentWorkerForBuilder + from buildbot.reporters.base import ReporterBase + # exceptions that can be raised while trying to start a build @@ -38,17 +53,17 @@ class WorkerSetupError(Exception): class LatentWorkerFailedToSubstantiate(Exception): - def __str__(self): + def __str__(self) -> str: return " ".join(str(arg) for arg in self.args) class LatentWorkerCannotSubstantiate(Exception): - def __str__(self): + def __str__(self) -> str: return " ".join(str(arg) for arg in self.args) class LatentWorkerSubstantiatiationCancelled(Exception): - def __str__(self): + def __str__(self) -> str: return " ".join(str(arg) for arg in self.args) @@ -71,8 +86,9 @@ class IChangeSource(IPlugin): master = Attribute('master', 'Pointer to BuildMaster, automatically set when started.') - def describe(): + def describe() -> str: """Return a string which briefly describes this source.""" + raise NotImplementedError class ISourceStamp(Interface): @@ -98,25 +114,29 @@ class ISourceStamp(Interface): @type repository: string """ - def canBeMergedWith(other): + def canBeMergedWith(other: 'ISourceStamp') -> bool: """ Can this SourceStamp be merged with OTHER? """ + raise NotImplementedError - def mergeWith(others): + def mergeWith(others: List['ISourceStamp']) -> 'ISourceStamp': """Generate a SourceStamp for the merger of me and all the other SourceStamps. This is called by a Build when it starts, to figure out what its sourceStamp should be.""" + raise NotImplementedError - def getAbsoluteSourceStamp(got_revision): + def getAbsoluteSourceStamp(got_revision: str) -> 'ISourceStamp': """Get a new SourceStamp object reflecting the actual revision found by a Source step.""" + raise NotImplementedError - def getText(): + def getText() -> str: """Returns a list of strings to describe the stamp. These are intended to be displayed in a narrow column. If more space is available, the caller should join them together with spaces before presenting them to the user.""" + raise NotImplementedError class IEmailSender(Interface): @@ -125,10 +145,11 @@ class IEmailSender(Interface): class IEmailLookup(Interface): - def getAddress(user): + def getAddress(user: str) -> "Deferred": """Turn a User-name string into a valid email address. Either return a string (with an @ in it), None (to indicate that the user cannot be reached by email), or a Deferred which will fire with the same.""" + raise NotImplementedError class ILogObserver(Interface): @@ -137,14 +158,14 @@ class ILogObserver(Interface): """ # internal methods - def setStep(step): + def setStep(step: "IBuildStep") -> None: pass - def setLog(log): + def setLog(log: "Log") -> None: pass # methods called by the LogFile - def logChunk(build, step, log, channel, text): + def logChunk(build: "Build", step: "IBuildStep", log: "Log", channel: str, text: str) -> None: pass @@ -161,27 +182,30 @@ class ILatentWorker(IWorker): 'Whether the latent worker is currently substantiated with a real instance.', ) - def substantiate(): + def substantiate() -> "Deferred": """Request that the worker substantiate with a real instance. Returns a deferred that will callback when a real instance has attached.""" + raise NotImplementedError # there is an insubstantiate too, but that is not used externally ATM. - def buildStarted(wfb): + def buildStarted(wfb: "LatentWorkerForBuilder") -> None: """Inform the latent worker that a build has started. @param wfb: a L{LatentWorkerForBuilder}. The wfb is the one for whom the build finished. """ + raise NotImplementedError - def buildFinished(wfb): + def buildFinished(wfb: "LatentWorkerForBuilder") -> None: """Inform the latent worker that a build has finished. @param wfb: a L{LatentWorkerForBuilder}. The wfb is the one for whom the build finished. """ + raise NotImplementedError class IMachine(Interface): @@ -189,7 +213,7 @@ class IMachine(Interface): class IMachineAction(Interface): - def perform(manager): + def perform(manager: IMachine) -> "Deferred": """Perform an action on the machine managed by manager. Returns a deferred evaluating to True if it was possible to execute the action. @@ -203,11 +227,12 @@ class ILatentMachine(IMachine): class IRenderable(Interface): """An object that can be interpolated with properties from a build.""" - def getRenderingFor(iprops): + def getRenderingFor(iprops: "IProperties") -> "Deferred": """Return a deferred that fires with interpolation with the given properties @param iprops: the L{IProperties} provider supplying the properties. """ + raise NotImplementedError class IProperties(Interface): @@ -215,7 +240,7 @@ class IProperties(Interface): An object providing access to build properties """ - def getProperty(name, default=None): + def getProperty(name: str, default: Any = None) -> object: """Get the named property, returning the default if the property does not exist. @@ -226,19 +251,22 @@ def getProperty(name, default=None): @returns: property value """ + raise NotImplementedError - def hasProperty(name): + def hasProperty(name: str) -> bool: """Return true if the named property exists. @param name: property name @type name: string @returns: boolean """ + raise NotImplementedError - def has_key(name): + def has_key(name: str) -> bool: """Deprecated name for L{hasProperty}.""" + raise NotImplementedError - def setProperty(name, value, source, runtime=False): + def setProperty(name: str, value: object, source: str, runtime: bool = False) -> None: """Set the given property, overwriting any existing value. The source describes the source of the value for human interpretation. @@ -256,7 +284,7 @@ def setProperty(name, value, source, runtime=False): @type runtime: boolean """ - def getProperties(): + def getProperties() -> "Properties": """Get the L{buildbot.process.properties.Properties} instance storing these properties. Note that the interface for this class is not stable, so where possible the other methods of this interface should be @@ -264,8 +292,9 @@ def getProperties(): @returns: L{buildbot.process.properties.Properties} instance """ + raise NotImplementedError - def getBuild(): + def getBuild() -> "Build": """Get the L{buildbot.process.build.Build} instance for the current build. Note that this object is not available after the build is complete, at which point this method will return None. @@ -275,8 +304,9 @@ def getBuild(): @returns L{buildbot.process.build.Build} instance """ + raise NotImplementedError - def render(value): + def render(value: Any) -> "IRenderable": """Render @code{value} as an L{IRenderable}. This essentially coerces @code{value} to an L{IRenderable} and calls its @L{getRenderingFor} method. @@ -284,6 +314,7 @@ def render(value): @name value: value to render @returns: rendered value """ + raise NotImplementedError class IScheduler(IPlugin): @@ -302,7 +333,7 @@ def trigger( class IBuildStepFactory(Interface): - def buildStep(): + def buildStep() -> None: pass @@ -315,41 +346,44 @@ class IBuildStep(IPlugin): class IConfigured(Interface): - def getConfigDict(): + def getConfigDict() -> Dict[str, Any]: return {} # return something to silence warnings at call sites class IReportGenerator(Interface): - def generate(master, reporter, key, build): - pass + def generate(master: "IConfigured", reporter: "ReporterBase", key: str, build: "Build") -> None: + raise NotImplementedError class IConfigLoader(Interface): - def loadConfig(): + def loadConfig() -> "MasterConfig": """ Load the specified configuration. :return MasterConfig: """ + raise NotImplementedError class IHttpResponse(Interface): - def content(): + def content() -> "Deferred": """ :returns: raw (``bytes``) content of the response via deferred """ + raise NotImplementedError - def json(): + def json() -> "Deferred": """ :returns: json decoded content of the response via deferred """ + raise NotImplementedError code = Attribute('code', "http status code of the request's response (e.g 200)") url = Attribute('url', "request's url (e.g https://api.github.com/endpoint')") class IConfigurator(Interface): - def configure(config_dict): + def configure(config_dict: Dict[str, Any]) -> None: """ Alter the buildbot config_dict, as defined in master.cfg @@ -358,3 +392,4 @@ def configure(config_dict): :returns: None """ + raise NotImplementedError