Question

I'm am making custom modifications to ReviewBoard (RBtools); however, I can't seem to understand what Python is doing implicitly at this step.

I am trying to understand where ReviewBoardServer sets its value for self.info.path.

I stepped through the debugger and traced it to the method check_api_version on the line

self.root_resource = root_resource

Prior to this statement, we have self.info as None, but it quickly changes to an SVNRepositoryInfo after the line above.

The line above does not set the class field of self.info in that line. I am guessing that Python is doing something under the hood that allows it to populate self._info by setting self.root_resource? Is this correct? If so, where would I find more information about this?

For reference the init method looks like:

 185 class ReviewBoardServer(object):
 186     """
 187     An instance of a Review Board server.
 188     """
 189     def __init__(self, url, info, cookie_file):
 190         self.url = url
 191         if self.url[-1] != '/':
 192             self.url += '/'
 193         self._info = info
 194         self._server_info = None
 195         self.capabilities = None
 196         self.root_resource = None
 197         self.deprecated_api = False
 198         self.rb_version = "0.0.0.0"
 199         self.cookie_file = cookie_file
 200         self.cookie_jar  = cookielib.MozillaCookieJar(self.cookie_file)
 201         self.deprecated_api = False
 202         self.root_resource = None

For reference, the specific file is hosted on Github below: https://github.com/reviewboard/rbtools/blob/release-0.4.3/rbtools/postreview.py

Was it helpful?

Solution

You can do things like that "under the hood" in Python using descriptors along with the built-inproperty() function. See Implementing Descriptors in the documentation for more details.

Thepostreview.pysource file has the line:

627     info = property(_get_server_info)

Which defines a__get__()function for theReviewBoardServerclass attribute namedinfo.

The definition of_get_server_info()is right above that in the source:

def _get_server_info(self):
    if not self._server_info:
        self._server_info = self._info.find_server_repository_info(self)

    return self._server_info

As you can see, whenever the value ofinfois retrieved, if the value ofself._server_infoisNone, it is set to something and then its value is returned as the value of the attribute.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top