Changeset - 31250d5e3c6a
[Not reviewed]
default
0 1 0
Mads Kiilerich - 6 years ago 2020-03-28 21:21:47
mads@kiilerich.com
Grafted from: 6ba98c5609cf
vcs: avoid node base class knowledge of sub classes

Pytype very reasonably got confused over the sub class property references in
the base class.

Fixed by moving base class specific parts of comparison to the sub classes and
calling the base class.

With .content only referenced in FileNode, there is even less need for an
explicitly failing .content getter for DirNode.
1 file changed with 29 insertions and 18 deletions:
0 comments (0 inline, 0 general)
kallithea/lib/vcs/nodes.py
Show inline comments
 
@@ -126,48 +126,34 @@ class Node(object):
 
        Returns name of the node so if its path
 
        then only last part is returned.
 
        """
 
        return self.path.rstrip('/').split('/')[-1]
 

	
 
    def __eq__(self, other):
 
        if type(self) is not type(other):
 
            return False
 
        if self.kind != other.kind:
 
            return False
 
        if self.path != other.path:
 
            return False
 
        if self.is_file():
 
            return self.content == other.content
 
        else:
 
            # For DirNode's check without entering each dir
 
            self_nodes_paths = list(sorted(n.path for n in self.nodes))
 
            other_nodes_paths = list(sorted(n.path for n in self.nodes))
 
            return self_nodes_paths == other_nodes_paths
 

	
 
    def __lt__(self, other):
 
        if self.kind < other.kind:
 
            return True
 
        if self.kind > other.kind:
 
            return False
 
        if self.path < other.path:
 
            return True
 
        if self.path > other.path:
 
            return False
 
        if self.is_file():
 
            return self.content < other.content
 
        else:
 
            # For DirNode's check without entering each dir
 
            self_nodes_paths = list(sorted(n.path for n in self.nodes))
 
            other_nodes_paths = list(sorted(n.path for n in self.nodes))
 
            return self_nodes_paths < other_nodes_paths
 

	
 
    def __repr__(self):
 
        return '<%s %r>' % (self.__class__.__name__, self.path)
 

	
 
    def get_parent_path(self):
 
        """
 
        Returns node's parent path or empty string if node is root.
 
        """
 
        if self.is_root():
 
            return ''
 
        return posixpath.dirname(self.path.rstrip('/')) + '/'
 

	
 
@@ -238,24 +224,36 @@ class FileNode(Node):
 

	
 
        if content and changeset:
 
            raise NodeError("Cannot use both content and changeset")
 
        super(FileNode, self).__init__(path, kind=NodeKind.FILE)
 
        self.changeset = changeset
 
        if not isinstance(content, bytes) and content is not None:
 
            # File content is one thing that inherently must be bytes ... but
 
            # VCS module tries to be "user friendly" and support unicode ...
 
            content = safe_bytes(content)
 
        self._content = content
 
        self._mode = mode or 0o100644
 

	
 
    def __eq__(self, other):
 
        eq = super(FileNode, self).__eq__(other)
 
        if eq is not None:
 
            return eq
 
        return self.content == other.content
 

	
 
    def __lt__(self, other):
 
        lt = super(FileNode, self).__lt__(other)
 
        if lt is not None:
 
            return lt
 
        return self.content < other.content
 

	
 
    @LazyProperty
 
    def mode(self):
 
        """
 
        Returns lazily mode of the FileNode. If ``changeset`` is not set, would
 
        use value given at initialization or 0100644 (default).
 
        """
 
        if self.changeset:
 
            mode = self.changeset.get_file_mode(self.path)
 
        else:
 
            mode = self._mode
 
        return mode
 

	
 
@@ -456,28 +454,41 @@ class DirNode(Node):
 

	
 
        :param path: relative path to the node
 
        :param nodes: content may be passed to constructor
 
        :param changeset: if given, will use it to lazily fetch content
 
        :param size: always 0 for ``DirNode``
 
        """
 
        if nodes and changeset:
 
            raise NodeError("Cannot use both nodes and changeset")
 
        super(DirNode, self).__init__(path, NodeKind.DIR)
 
        self.changeset = changeset
 
        self._nodes = nodes
 

	
 
    @LazyProperty
 
    def content(self):
 
        raise NodeError("%s represents a dir and has no ``content`` attribute"
 
            % self)
 
    def __eq__(self, other):
 
        eq = super(DirNode, self).__eq__(other)
 
        if eq is not None:
 
            return eq
 
        # check without entering each dir
 
        self_nodes_paths = list(sorted(n.path for n in self.nodes))
 
        other_nodes_paths = list(sorted(n.path for n in self.nodes))
 
        return self_nodes_paths == other_nodes_paths
 

	
 
    def __lt__(self, other):
 
        lt = super(DirNode, self).__lt__(other)
 
        if lt is not None:
 
            return lt
 
        # check without entering each dir
 
        self_nodes_paths = list(sorted(n.path for n in self.nodes))
 
        other_nodes_paths = list(sorted(n.path for n in self.nodes))
 
        return self_nodes_paths < other_nodes_paths
 

	
 
    @LazyProperty
 
    def nodes(self):
 
        if self.changeset:
 
            nodes = self.changeset.get_nodes(self.path)
 
        else:
 
            nodes = self._nodes
 
        self._nodes_dict = dict((node.path, node) for node in nodes)
 
        return sorted(nodes)
 

	
 
    @LazyProperty
 
    def files(self):
0 comments (0 inline, 0 general)