eric7/Plugins/CheckerPlugins/CodeStyleChecker/Imports/ImportNode.py

branch
eric7
changeset 8802
129a973fc33e
child 8808
033fa34447d0
equal deleted inserted replaced
8801:8fbb21be8579 8802:129a973fc33e
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2021 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a class representing an import or import from node.
8 """
9
10 #
11 # adapted from flake8-alphabetize v0.0.17
12 #
13
14 import ast
15 from functools import total_ordering
16
17 from .ImportsEnums import GroupEnum, NodeTypeEnum
18
19
20 class ImportNodeException(Exception):
21 """
22 Class representing an exception for an invalid import node.
23 """
24 pass
25
26
27 @total_ordering
28 class ImportNode:
29 """
30 Class representing an import or import from node.
31 """
32 def __init__(self, appNames, astNode, checker):
33 """
34 Constructor
35
36 @param appNames list of application package names
37 @type list of str
38 @param astNode reference to the ast node
39 @type ast.AST
40 @param checker reference to the checker object
41 @type ImportsChecker
42 @exception ImportNodeException raised to indicate an invalid node was
43 given to this class
44 """
45 if (
46 self.nodeType not in (NodeTypeEnum.IMPORT,
47 NodeTypeEnum.IMPORT_FROM)
48 ):
49 raise ImportNodeException(
50 "Node type {0} not recognized".format(type(astNode))
51 )
52
53 self.node = astNode
54 self.error = None
55 level = None
56 group = None
57
58 if isinstance(astNode, ast.Import):
59 self.nodeType = NodeTypeEnum.IMPORT
60 names = astNode.names
61
62 self.moduleName = names[0].name
63 level = 0
64
65 elif isinstance(astNode, ast.ImportFrom):
66 module = astNode.module
67 self.moduleName = "" if module is None else module
68 self.nodeType = NodeTypeEnum.IMPORT_FROM
69
70 names = [n.name for n in astNode.names]
71 expectedNames = sorted(names)
72 if names != expectedNames:
73 self.error = (self.node, "I202", ", ".join(expectedNames))
74 level = astNode.level
75
76 if self.moduleName == "__future__":
77 group = GroupEnum.FUTURE
78 elif self.moduleName in checker.getStandardModules():
79 group = GroupEnum.STDLIB
80 elif level > 0:
81 group = GroupEnum.APPLICATION
82 else:
83 group = GroupEnum.THIRD_PARTY
84 for name in appNames:
85 if (
86 name == self.moduleName or
87 self.moduleName.startswith("{0}.".format(name))
88 ):
89 group = GroupEnum.APPLICATION
90 break
91
92 if group == GroupEnum.STDLIB:
93 self.sorter = group, self.nodeType, self.moduleName
94 else:
95 m = self.moduleName
96 dotIndex = m.find(".")
97 topName = m if dotIndex == -1 else m[:dotIndex]
98 self.sorter = group, level, topName, self.nodeType, m
99
100 def __eq__(self, other):
101 """
102 Special method implementing the equality operator.
103
104 @param other reference to the object to compare
105 @type ImportNode
106 @return flag indicating equality
107 @rtype bool
108 """
109 return self.sorter == other.sorter
110
111 def __lt__(self, other):
112 """
113 Special method implementing the less than operator.
114
115 @param other reference to the object to compare
116 @type ImportNode
117 @return flag indicating a less than situation
118 @rtype bool
119 """
120 return self.sorter < other.sorter
121
122 def __str__(self):
123 """
124 Special method to create a string representation of the instance.
125
126 @return string representation of the instance
127 @rtype str
128 @exception ImportNodeException raised to indicate an invalid node was
129 given to this class
130 """
131 if (
132 self.nodeType not in (NodeTypeEnum.IMPORT,
133 NodeTypeEnum.IMPORT_FROM)
134 ):
135 raise ImportNodeException(
136 "The node type {0} is not recognized.".format(self.nodeType)
137 )
138
139 if self.nodeType == NodeTypeEnum.IMPORT:
140 return "import {0}".format(self.moduleName)
141 elif self.nodeType == NodeTypeEnum.IMPORT_FROM:
142 level = self.node.level
143 levelStr = "" if level == 0 else "." * level
144 names = [
145 n.name + ("" if n.asname is None else
146 " as {0}".format(n.asname))
147 for n in self.node.names
148 ]
149 return "from {0}{1} import {2}".format(
150 levelStr, self.moduleName, ", ".join(names))
151
152 return None

eric ide

mercurial