MCPcopy Create free account
hub / github.com/StackStorm/st2 / transform

Function transform

pylint_plugins/api_models.py:100–339  ·  view source on GitHub ↗

Astroid (used by pylint) calls this function on each class definition it discovers. cls is an Astroid AST representation of that class. Our purpose here is to extract the schema dict from API model classes so that we can inform pylint about all of the attributes on those models.

(cls: nodes.ClassDef)

Source from the content-addressed store, hash-verified

98
99
100def transform(cls: nodes.ClassDef):
101 """
102 Astroid (used by pylint) calls this function on each class definition it discovers.
103 cls is an Astroid AST representation of that class.
104
105 Our purpose here is to extract the schema dict from API model classes
106 so that we can inform pylint about all of the attributes on those models.
107 We do this by injecting attributes on the class for each property in the schema.
108 """
109
110 # This is a class which defines attributes in "schema" variable using json schema.
111 # Those attributes are then assigned during run time inside the constructor
112
113 # Get the value node for the "schema =" assignment
114 schema_dict_node = next(cls.igetattr("schema"))
115
116 extra_schema_properties = {}
117
118 # If the "schema =" assignment's value node is not a simple type (like a dictionary),
119 # then pylint cannot infer exactly what it does. Most of the time, this is actually
120 # a function call to copy the schema from another class. So, let's find the dictionary.
121 if schema_dict_node is astroid.Uninferable:
122 # the assignment probably looks like this:
123 # schema = copy.deepcopy(ActionAPI.schema)
124
125 # so far we only have the value, but we need the actual assignment
126 assigns = [n for n in cls.get_children() if isinstance(n, nodes.Assign)]
127 schema_assign_name_node = cls.local_attr("schema")[0]
128 schema_assign_node = next(
129 assign for assign in assigns if assign.targets[0] == schema_assign_name_node
130 )
131 assigns.remove(schema_assign_node)
132
133 # We only care about "schema = copy.deepcopy(...)"
134 schema_dict_node = infer_copy_deepcopy(schema_assign_node.value)
135 if not schema_dict_node:
136 # This is not an API model class, as it doesn't have
137 # something we can resolve to a dictionary.
138 return
139
140 # OK, now we need to look for any properties that dynamically modify
141 # the dictionary that was just copied from somewhere else.
142 # See the note below for why we only care about "properties" here.
143 for assign_node in assigns:
144 # we're looking for assignments like this:
145 # schema["properties"]["ttl"] = {...}
146 target = assign_node.targets[0]
147 try:
148 if (
149 isinstance(target, nodes.Subscript)
150 and target.value.value.name == "schema"
151 ):
152 if (
153 isinstance(target.value.slice.value, nodes.Const)
154 and target.value.slice.value.value == "properties"
155 ):
156 # python <3.9
157 property_name_node = target.slice.value

Callers

nothing calls this directly

Calls 3

infer_copy_deepcopyFunction · 0.85
get_childrenMethod · 0.80
removeMethod · 0.80

Tested by

no test coverage detected