MCPcopy Index your code
hub / github.com/python/cpython / ImportParser

Class ImportParser

Lib/_pyrepl/_module_completer.py:304–449  ·  view source on GitHub ↗

Parses incomplete import statements that are suitable for autocomplete suggestions. Examples: - import foo -> Result(from_name=None, name='foo') - import foo. -> Result(from_name=None, name='foo.') - from foo -> Result(from_name='foo'

Source from the content-addressed store, hash-verified

302
303
304class ImportParser:
305 """
306 Parses incomplete import statements that are
307 suitable for autocomplete suggestions.
308
309 Examples:
310 - import foo -> Result(from_name=None, name='foo')
311 - import foo. -> Result(from_name=None, name='foo.')
312 - from foo -> Result(from_name='foo', name=None)
313 - from foo import bar -> Result(from_name='foo', name='bar')
314 - from .foo import ( -> Result(from_name='.foo', name='')
315
316 Note that the parser works in reverse order, starting from the
317 last token in the input string. This makes the parser more robust
318 when parsing multiple statements.
319 """
320 _ignored_tokens = {
321 token.INDENT, token.DEDENT, token.COMMENT,
322 token.NL, token.NEWLINE, token.ENDMARKER
323 }
324 _keywords = {'import', 'from', 'as'}
325
326 def __init__(self, code: str) -> None:
327 self.code = code
328 tokens = []
329 try:
330 for t in tokenize.generate_tokens(StringIO(code).readline):
331 if t.type not in self._ignored_tokens:
332 tokens.append(t)
333 except tokenize.TokenError as e:
334 if 'unexpected EOF' not in str(e):
335 # unexpected EOF is fine, since we're parsing an
336 # incomplete statement, but other errors are not
337 # because we may not have all the tokens so it's
338 # safer to bail out
339 tokens = []
340 except SyntaxError:
341 tokens = []
342 self.tokens = TokenQueue(tokens[::-1])
343
344 def parse(self) -> tuple[str | None, str | None] | None:
345 if not (res := self._parse()):
346 return None
347 return res.from_name, res.name
348
349 def _parse(self) -> Result | None:
350 with self.tokens.save_state():
351 return self.parse_from_import()
352 with self.tokens.save_state():
353 return self.parse_import()
354
355 def parse_import(self) -> Result:
356 if self.code.rstrip().endswith('import') and self.code.endswith(' '):
357 return Result(name='')
358 if self.tokens.peek_string(','):
359 name = ''
360 else:
361 if self.code.endswith(' '):

Callers 3

test_parseMethod · 0.90
test_parse_errorMethod · 0.90
get_completionsMethod · 0.85

Calls

no outgoing calls

Tested by 2

test_parseMethod · 0.72
test_parse_errorMethod · 0.72

Used in the wild real call sites across dependent graphs

searching dependent graphs…