The previous fix to this area worked, but was dropping bytes in
dict on Python 3. This was causing subtle breakage in
test-check-interfaces.py, and probably other things too.
Fixed now.
| hg-reviewers |
The previous fix to this area worked, but was dropping bytes in
dict on Python 3. This was causing subtle breakage in
test-check-interfaces.py, and probably other things too.
Fixed now.
| Lint Skipped |
| Unit Tests Skipped |
| Path | Packages | |||
|---|---|---|---|---|
| M | mercurial/scmutil.py (13 lines) |
| Commit | Parents | Author | Summary | Date |
|---|---|---|---|---|
| Augie Fackler | Apr 26 2018, 9:38 PM |
| Users should subclass filecache and provide their own version of this | Users should subclass filecache and provide their own version of this | ||||
| function to call the appropriate join function on 'obj' (an instance | function to call the appropriate join function on 'obj' (an instance | ||||
| of the class that its member function was decorated). | of the class that its member function was decorated). | ||||
| """ | """ | ||||
| raise NotImplementedError | raise NotImplementedError | ||||
| def __call__(self, func): | def __call__(self, func): | ||||
| self.func = func | self.func = func | ||||
| self.name = func.__name__.encode('ascii') | self.sname = func.__name__ | ||||
| self.name = pycompat.sysbytes(self.sname) | |||||
| return self | return self | ||||
| def __get__(self, obj, type=None): | def __get__(self, obj, type=None): | ||||
| # if accessed on the class, return the descriptor itself. | # if accessed on the class, return the descriptor itself. | ||||
| if obj is None: | if obj is None: | ||||
| return self | return self | ||||
| # do we need to check if the file changed? | # do we need to check if the file changed? | ||||
| if self.name in obj.__dict__: | if self.sname in obj.__dict__: | ||||
| assert self.name in obj._filecache, self.name | assert self.name in obj._filecache, self.name | ||||
| return obj.__dict__[self.name] | return obj.__dict__[self.sname] | ||||
| entry = obj._filecache.get(self.name) | entry = obj._filecache.get(self.name) | ||||
| if entry: | if entry: | ||||
| if entry.changed(): | if entry.changed(): | ||||
| entry.obj = self.func(obj) | entry.obj = self.func(obj) | ||||
| else: | else: | ||||
| paths = [self.join(obj, path) for path in self.paths] | paths = [self.join(obj, path) for path in self.paths] | ||||
| # We stat -before- creating the object so our cache doesn't lie if | # We stat -before- creating the object so our cache doesn't lie if | ||||
| # a writer modified between the time we read and stat | # a writer modified between the time we read and stat | ||||
| entry = filecacheentry(paths, True) | entry = filecacheentry(paths, True) | ||||
| entry.obj = self.func(obj) | entry.obj = self.func(obj) | ||||
| obj._filecache[self.name] = entry | obj._filecache[self.name] = entry | ||||
| obj.__dict__[self.name] = entry.obj | obj.__dict__[self.sname] = entry.obj | ||||
| return entry.obj | return entry.obj | ||||
| def __set__(self, obj, value): | def __set__(self, obj, value): | ||||
| if self.name not in obj._filecache: | if self.name not in obj._filecache: | ||||
| # we add an entry for the missing value because X in __dict__ | # we add an entry for the missing value because X in __dict__ | ||||
| # implies X in _filecache | # implies X in _filecache | ||||
| paths = [self.join(obj, path) for path in self.paths] | paths = [self.join(obj, path) for path in self.paths] | ||||
| ce = filecacheentry(paths, False) | ce = filecacheentry(paths, False) | ||||
| obj._filecache[self.name] = ce | obj._filecache[self.name] = ce | ||||
| else: | else: | ||||
| ce = obj._filecache[self.name] | ce = obj._filecache[self.name] | ||||
| ce.obj = value # update cached copy | ce.obj = value # update cached copy | ||||
| obj.__dict__[self.name] = value # update copy returned by obj.x | obj.__dict__[self.sname] = value # update copy returned by obj.x | ||||
| def __delete__(self, obj): | def __delete__(self, obj): | ||||
| try: | try: | ||||
| del obj.__dict__[self.name] | del obj.__dict__[self.sname] | ||||
| except KeyError: | except KeyError: | ||||
| raise AttributeError(self.name) | raise AttributeError(self.name) | ||||
| def extdatasource(repo, source): | def extdatasource(repo, source): | ||||
| """Gather a map of rev -> value dict from the specified source | """Gather a map of rev -> value dict from the specified source | ||||
| A source spec is treated as a URL, with a special case shell: type | A source spec is treated as a URL, with a special case shell: type | ||||
| for parsing the output from a shell command. | for parsing the output from a shell command. | ||||