| 307 | |
| 308 | |
| 309 | class TokenEater: |
| 310 | def __init__(self, options): |
| 311 | self.__options = options |
| 312 | self.__messages = {} |
| 313 | self.__state = self.__waiting |
| 314 | self.__data = [] |
| 315 | self.__lineno = -1 |
| 316 | self.__freshmodule = 1 |
| 317 | self.__curfile = None |
| 318 | self.__enclosurecount = 0 |
| 319 | |
| 320 | def __call__(self, ttype, tstring, stup, etup, line): |
| 321 | # dispatch |
| 322 | ## import token |
| 323 | ## print('ttype:', token.tok_name[ttype], 'tstring:', tstring, |
| 324 | ## file=sys.stderr) |
| 325 | self.__state(ttype, tstring, stup[0]) |
| 326 | |
| 327 | def __waiting(self, ttype, tstring, lineno): |
| 328 | opts = self.__options |
| 329 | # Do docstring extractions, if enabled |
| 330 | if opts.docstrings and not opts.nodocstrings.get(self.__curfile): |
| 331 | # module docstring? |
| 332 | if self.__freshmodule: |
| 333 | if ttype == tokenize.STRING and is_literal_string(tstring): |
| 334 | self.__addentry(safe_eval(tstring), lineno, isdocstring=1) |
| 335 | self.__freshmodule = 0 |
| 336 | return |
| 337 | if ttype in (tokenize.COMMENT, tokenize.NL, tokenize.ENCODING): |
| 338 | return |
| 339 | self.__freshmodule = 0 |
| 340 | # class or func/method docstring? |
| 341 | if ttype == tokenize.NAME and tstring in ('class', 'def'): |
| 342 | self.__state = self.__suiteseen |
| 343 | return |
| 344 | if ttype == tokenize.NAME and tstring in opts.keywords: |
| 345 | self.__state = self.__keywordseen |
| 346 | return |
| 347 | if ttype == tokenize.STRING: |
| 348 | maybe_fstring = ast.parse(tstring, mode='eval').body |
| 349 | if not isinstance(maybe_fstring, ast.JoinedStr): |
| 350 | return |
| 351 | for value in filter(lambda node: isinstance(node, ast.FormattedValue), |
| 352 | maybe_fstring.values): |
| 353 | for call in filter(lambda node: isinstance(node, ast.Call), |
| 354 | ast.walk(value)): |
| 355 | func = call.func |
| 356 | if isinstance(func, ast.Name): |
| 357 | func_name = func.id |
| 358 | elif isinstance(func, ast.Attribute): |
| 359 | func_name = func.attr |
| 360 | else: |
| 361 | continue |
| 362 | |
| 363 | if func_name not in opts.keywords: |
| 364 | continue |
| 365 | if len(call.args) != 1: |
| 366 | print(_( |