Add symbol table node to the currently active symbol table. Return True if we actually added the symbol, or False if we refused to do so (because something is not ready or it was a no-op). Generate an error if there is an invalid redefinition. If context is None, u
(
self,
name: str,
symbol: SymbolTableNode,
context: Context | None = None,
can_defer: bool = True,
escape_comprehensions: bool = False,
no_progress: bool = False,
type_param: bool = False,
)
| 7058 | names[name] = symbol |
| 7059 | |
| 7060 | def add_symbol_table_node( |
| 7061 | self, |
| 7062 | name: str, |
| 7063 | symbol: SymbolTableNode, |
| 7064 | context: Context | None = None, |
| 7065 | can_defer: bool = True, |
| 7066 | escape_comprehensions: bool = False, |
| 7067 | no_progress: bool = False, |
| 7068 | type_param: bool = False, |
| 7069 | ) -> bool: |
| 7070 | """Add symbol table node to the currently active symbol table. |
| 7071 | |
| 7072 | Return True if we actually added the symbol, or False if we refused |
| 7073 | to do so (because something is not ready or it was a no-op). |
| 7074 | |
| 7075 | Generate an error if there is an invalid redefinition. |
| 7076 | |
| 7077 | If context is None, unconditionally add node, since we can't report |
| 7078 | an error. Note that this is used by plugins to forcibly replace nodes! |
| 7079 | |
| 7080 | TODO: Prevent plugins from replacing nodes, as it could cause problems? |
| 7081 | |
| 7082 | Args: |
| 7083 | name: short name of symbol |
| 7084 | symbol: Node to add |
| 7085 | can_defer: if True, defer current target if adding a placeholder |
| 7086 | context: error context (see above about None value) |
| 7087 | """ |
| 7088 | names = self.current_symbol_table( |
| 7089 | escape_comprehensions=escape_comprehensions, type_param=type_param |
| 7090 | ) |
| 7091 | existing = names.get(name) |
| 7092 | if isinstance(symbol.node, PlaceholderNode) and can_defer: |
| 7093 | if context is not None: |
| 7094 | self.process_placeholder(name, "name", context) |
| 7095 | else: |
| 7096 | # see note in docstring describing None contexts |
| 7097 | self.defer() |
| 7098 | |
| 7099 | if ( |
| 7100 | existing is not None |
| 7101 | and context is not None |
| 7102 | and not is_valid_replacement(existing, symbol) |
| 7103 | ): |
| 7104 | # There is an existing node, so this may be a redefinition. |
| 7105 | # If the new node points to the same node as the old one, |
| 7106 | # or if both old and new nodes are placeholders, we don't |
| 7107 | # need to do anything. |
| 7108 | old = existing.node |
| 7109 | new = symbol.node |
| 7110 | if isinstance(new, PlaceholderNode): |
| 7111 | # We don't know whether this is okay. Let's wait until the next iteration. |
| 7112 | return False |
| 7113 | if not is_same_symbol(old, new): |
| 7114 | if isinstance(new, (FuncDef, Decorator, OverloadedFuncDef, TypeInfo)): |
| 7115 | self.add_redefinition(names, name, symbol) |
| 7116 | if isinstance(old, Var) and is_init_only(old): |
| 7117 | if old.has_explicit_value: |
no test coverage detected