pyflyby 1.8.9__tar.gz → 1.9.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pyflyby might be problematic. Click here for more details.

Files changed (149) hide show
  1. {pyflyby-1.8.9/lib/python/pyflyby.egg-info → pyflyby-1.9.1}/PKG-INFO +1 -1
  2. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/pyflyby/_autoimp.py +59 -20
  3. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/pyflyby/_comms.py +21 -12
  4. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/pyflyby/_dbg.py +8 -9
  5. {pyflyby-1.8.9/lib/python → pyflyby-1.9.1/bin}/pyflyby/_docxref.py +2 -3
  6. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/pyflyby/_file.py +5 -8
  7. {pyflyby-1.8.9/lib/python → pyflyby-1.9.1/bin}/pyflyby/_flags.py +9 -5
  8. {pyflyby-1.8.9/lib/python → pyflyby-1.9.1/bin}/pyflyby/_format.py +5 -6
  9. {pyflyby-1.8.9/lib/python → pyflyby-1.9.1/bin}/pyflyby/_idents.py +10 -10
  10. {pyflyby-1.8.9/lib/python → pyflyby-1.9.1/bin}/pyflyby/_importclns.py +15 -16
  11. {pyflyby-1.8.9/lib/python → pyflyby-1.9.1/bin}/pyflyby/_importdb.py +5 -5
  12. {pyflyby-1.8.9/lib/python → pyflyby-1.9.1/bin}/pyflyby/_imports2s.py +1 -0
  13. {pyflyby-1.8.9/lib/python → pyflyby-1.9.1/bin}/pyflyby/_importstmt.py +37 -26
  14. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/pyflyby/_interactive.py +22 -3
  15. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/pyflyby/_livepatch.py +4 -4
  16. {pyflyby-1.8.9/lib/python → pyflyby-1.9.1/bin}/pyflyby/_modules.py +16 -13
  17. {pyflyby-1.8.9/lib/python → pyflyby-1.9.1/bin}/pyflyby/_parse.py +41 -14
  18. {pyflyby-1.8.9/lib/python → pyflyby-1.9.1/bin}/pyflyby/_py.py +36 -30
  19. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/pyflyby/_util.py +23 -46
  20. {pyflyby-1.8.9/lib/python → pyflyby-1.9.1/bin}/pyflyby/_version.py +1 -1
  21. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/tidy-imports +8 -3
  22. {pyflyby-1.8.9 → pyflyby-1.9.1}/etc/pyflyby/std.py +1 -1
  23. {pyflyby-1.8.9 → pyflyby-1.9.1}/lib/python/pyflyby/_autoimp.py +59 -20
  24. {pyflyby-1.8.9 → pyflyby-1.9.1}/lib/python/pyflyby/_comms.py +21 -12
  25. {pyflyby-1.8.9 → pyflyby-1.9.1}/lib/python/pyflyby/_dbg.py +8 -9
  26. {pyflyby-1.8.9/bin → pyflyby-1.9.1/lib/python}/pyflyby/_docxref.py +2 -3
  27. {pyflyby-1.8.9 → pyflyby-1.9.1}/lib/python/pyflyby/_file.py +5 -8
  28. {pyflyby-1.8.9/bin → pyflyby-1.9.1/lib/python}/pyflyby/_flags.py +9 -5
  29. {pyflyby-1.8.9/bin → pyflyby-1.9.1/lib/python}/pyflyby/_format.py +5 -6
  30. {pyflyby-1.8.9/bin → pyflyby-1.9.1/lib/python}/pyflyby/_idents.py +10 -10
  31. {pyflyby-1.8.9/bin → pyflyby-1.9.1/lib/python}/pyflyby/_importclns.py +15 -16
  32. {pyflyby-1.8.9/bin → pyflyby-1.9.1/lib/python}/pyflyby/_importdb.py +5 -5
  33. {pyflyby-1.8.9/bin → pyflyby-1.9.1/lib/python}/pyflyby/_imports2s.py +1 -0
  34. {pyflyby-1.8.9/bin → pyflyby-1.9.1/lib/python}/pyflyby/_importstmt.py +37 -26
  35. {pyflyby-1.8.9 → pyflyby-1.9.1}/lib/python/pyflyby/_interactive.py +22 -3
  36. {pyflyby-1.8.9 → pyflyby-1.9.1}/lib/python/pyflyby/_livepatch.py +4 -4
  37. {pyflyby-1.8.9/bin → pyflyby-1.9.1/lib/python}/pyflyby/_modules.py +16 -13
  38. {pyflyby-1.8.9/bin → pyflyby-1.9.1/lib/python}/pyflyby/_parse.py +41 -14
  39. {pyflyby-1.8.9/bin → pyflyby-1.9.1/lib/python}/pyflyby/_py.py +36 -30
  40. {pyflyby-1.8.9 → pyflyby-1.9.1}/lib/python/pyflyby/_util.py +23 -46
  41. {pyflyby-1.8.9/bin → pyflyby-1.9.1/lib/python}/pyflyby/_version.py +1 -1
  42. {pyflyby-1.8.9 → pyflyby-1.9.1/lib/python/pyflyby.egg-info}/PKG-INFO +1 -1
  43. {pyflyby-1.8.9 → pyflyby-1.9.1}/lib/python/pyflyby.egg-info/SOURCES.txt +1 -0
  44. {pyflyby-1.8.9 → pyflyby-1.9.1}/setup.py +1 -1
  45. {pyflyby-1.8.9 → pyflyby-1.9.1}/tests/test_autoimp.py +44 -7
  46. {pyflyby-1.8.9 → pyflyby-1.9.1}/tests/test_cmdline.py +1 -28
  47. {pyflyby-1.8.9 → pyflyby-1.9.1}/tests/test_importstmt.py +67 -2
  48. {pyflyby-1.8.9 → pyflyby-1.9.1}/tests/test_interactive.py +39 -271
  49. {pyflyby-1.8.9 → pyflyby-1.9.1}/tests/test_modules.py +31 -17
  50. {pyflyby-1.8.9 → pyflyby-1.9.1}/tests/test_parse.py +0 -18
  51. {pyflyby-1.8.9 → pyflyby-1.9.1}/tests/test_py.py +2 -5
  52. pyflyby-1.9.1/tests/tests_sorts.py +94 -0
  53. {pyflyby-1.8.9 → pyflyby-1.9.1}/.pyflyby +0 -0
  54. {pyflyby-1.8.9 → pyflyby-1.9.1}/LICENSE.txt +0 -0
  55. {pyflyby-1.8.9 → pyflyby-1.9.1}/MANIFEST.in +0 -0
  56. {pyflyby-1.8.9 → pyflyby-1.9.1}/README.rst +0 -0
  57. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/autoipython +0 -0
  58. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/autopython +0 -0
  59. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/collect-exports +0 -0
  60. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/collect-imports +0 -0
  61. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/create-imports +0 -0
  62. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/find-import +0 -0
  63. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/list-bad-xrefs +0 -0
  64. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/prune-broken-imports +0 -0
  65. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/py +0 -0
  66. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/pyflyby/__init__.py +0 -0
  67. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/pyflyby/__main__.py +0 -0
  68. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/pyflyby/_cmdline.py +0 -0
  69. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/pyflyby/_log.py +0 -0
  70. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/pyflyby/autoimport.py +0 -0
  71. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/pyflyby/importdb.py +0 -0
  72. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/pyflyby-diff +0 -0
  73. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/reformat-imports +0 -0
  74. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/replace-star-imports +0 -0
  75. {pyflyby-1.8.9 → pyflyby-1.9.1}/bin/transform-imports +0 -0
  76. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/LICENSE.txt +0 -0
  77. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/Makefile +0 -0
  78. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/TODO.txt +0 -0
  79. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/__init__.py +0 -0
  80. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/api/api.rst +0 -0
  81. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/api/autoimp.rst +0 -0
  82. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/api/cmdline.rst +0 -0
  83. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/api/comms.rst +0 -0
  84. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/api/dbg.rst +0 -0
  85. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/api/file.rst +0 -0
  86. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/api/flags.rst +0 -0
  87. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/api/format.rst +0 -0
  88. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/api/idents.rst +0 -0
  89. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/api/importclns.rst +0 -0
  90. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/api/importdb.rst +0 -0
  91. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/api/imports2s.rst +0 -0
  92. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/api/importstmt.rst +0 -0
  93. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/api/interactive.rst +0 -0
  94. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/api/livepatch.rst +0 -0
  95. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/api/log.rst +0 -0
  96. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/api/modules.rst +0 -0
  97. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/api/parse.rst +0 -0
  98. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/api/py.rst +0 -0
  99. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/api/util.rst +0 -0
  100. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/cli/autoipython.rst +0 -0
  101. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/cli/cli.rst +0 -0
  102. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/cli/collect_exports.rst +0 -0
  103. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/cli/collect_imports.rst +0 -0
  104. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/cli/find_import.rst +0 -0
  105. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/cli/prune_broken_imports.rst +0 -0
  106. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/cli/py.rst +0 -0
  107. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/cli/pyflyby_diff.rst +0 -0
  108. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/cli/reformat_imports.rst +0 -0
  109. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/cli/replace_star_imports.rst +0 -0
  110. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/cli/tidy_imports.rst +0 -0
  111. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/cli/transform_imports.rst +0 -0
  112. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/conf.py +0 -0
  113. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/index.rst +0 -0
  114. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/make.bat +0 -0
  115. {pyflyby-1.8.9 → pyflyby-1.9.1}/doc/testing.txt +0 -0
  116. {pyflyby-1.8.9 → pyflyby-1.9.1}/etc/pyflyby/canonical.py +0 -0
  117. {pyflyby-1.8.9 → pyflyby-1.9.1}/etc/pyflyby/common.py +0 -0
  118. {pyflyby-1.8.9 → pyflyby-1.9.1}/etc/pyflyby/forget.py +0 -0
  119. {pyflyby-1.8.9 → pyflyby-1.9.1}/etc/pyflyby/mandatory.py +0 -0
  120. {pyflyby-1.8.9 → pyflyby-1.9.1}/etc/pyflyby/numpy.py +0 -0
  121. {pyflyby-1.8.9 → pyflyby-1.9.1}/lib/emacs/pyflyby.el +0 -0
  122. {pyflyby-1.8.9 → pyflyby-1.9.1}/lib/python/pyflyby/__init__.py +0 -0
  123. {pyflyby-1.8.9 → pyflyby-1.9.1}/lib/python/pyflyby/__main__.py +0 -0
  124. {pyflyby-1.8.9 → pyflyby-1.9.1}/lib/python/pyflyby/_cmdline.py +0 -0
  125. {pyflyby-1.8.9 → pyflyby-1.9.1}/lib/python/pyflyby/_log.py +0 -0
  126. {pyflyby-1.8.9 → pyflyby-1.9.1}/lib/python/pyflyby/autoimport.py +0 -0
  127. {pyflyby-1.8.9 → pyflyby-1.9.1}/lib/python/pyflyby/importdb.py +0 -0
  128. {pyflyby-1.8.9 → pyflyby-1.9.1}/lib/python/pyflyby.egg-info/dependency_links.txt +0 -0
  129. {pyflyby-1.8.9 → pyflyby-1.9.1}/lib/python/pyflyby.egg-info/entry_points.txt +0 -0
  130. {pyflyby-1.8.9 → pyflyby-1.9.1}/lib/python/pyflyby.egg-info/requires.txt +0 -0
  131. {pyflyby-1.8.9 → pyflyby-1.9.1}/lib/python/pyflyby.egg-info/top_level.txt +0 -0
  132. {pyflyby-1.8.9 → pyflyby-1.9.1}/libexec/pyflyby/colordiff +0 -0
  133. {pyflyby-1.8.9 → pyflyby-1.9.1}/libexec/pyflyby/diff-colorize +0 -0
  134. {pyflyby-1.8.9 → pyflyby-1.9.1}/setup.cfg +0 -0
  135. {pyflyby-1.8.9 → pyflyby-1.9.1}/tests/__init__.py +0 -0
  136. {pyflyby-1.8.9 → pyflyby-1.9.1}/tests/test_0testconfig.py +0 -0
  137. {pyflyby-1.8.9 → pyflyby-1.9.1}/tests/test_docxref.py +0 -0
  138. {pyflyby-1.8.9 → pyflyby-1.9.1}/tests/test_file.py +0 -0
  139. {pyflyby-1.8.9 → pyflyby-1.9.1}/tests/test_flags.py +0 -0
  140. {pyflyby-1.8.9 → pyflyby-1.9.1}/tests/test_format.py +0 -0
  141. {pyflyby-1.8.9 → pyflyby-1.9.1}/tests/test_idents.py +0 -0
  142. {pyflyby-1.8.9 → pyflyby-1.9.1}/tests/test_importclns.py +0 -0
  143. {pyflyby-1.8.9 → pyflyby-1.9.1}/tests/test_importdb.py +0 -0
  144. {pyflyby-1.8.9 → pyflyby-1.9.1}/tests/test_imports2s.py +0 -0
  145. {pyflyby-1.8.9 → pyflyby-1.9.1}/tests/test_jupyterlab_pyflyby.py +0 -0
  146. {pyflyby-1.8.9 → pyflyby-1.9.1}/tests/test_livepatch.py +0 -0
  147. {pyflyby-1.8.9 → pyflyby-1.9.1}/tests/test_util.py +0 -0
  148. {pyflyby-1.8.9 → pyflyby-1.9.1}/tests/xrefs.py +0 -0
  149. {pyflyby-1.8.9 → pyflyby-1.9.1}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyflyby
3
- Version: 1.8.9
3
+ Version: 1.9.1
4
4
  Summary: pyflyby - Python development productivity tools, in particular automatic import management
5
5
  Home-page: https://pypi.org/project/pyflyby/
6
6
  Author: Karl Chen
@@ -5,11 +5,10 @@
5
5
 
6
6
 
7
7
  import ast
8
+ import builtins
8
9
  import contextlib
9
10
  import copy
10
- import six
11
- from six import exec_, reraise
12
- from six.moves import builtins
11
+ from six import reraise
13
12
  import sys
14
13
  import types
15
14
 
@@ -23,8 +22,22 @@ from pyflyby._importdb import ImportDB
23
22
  from pyflyby._importstmt import Import
24
23
  from pyflyby._log import logger
25
24
  from pyflyby._modules import ModuleHandle
26
- from pyflyby._parse import PythonBlock, infer_compile_mode
25
+ from pyflyby._parse import PythonBlock, infer_compile_mode, _is_ast_str
27
26
 
27
+ if sys.version_info >= (3, 12):
28
+ ATTRIBUTE_NAME = "value"
29
+ else:
30
+ ATTRIBUTE_NAME = "s"
31
+
32
+ if sys.version_info > (3, 11):
33
+ LOAD_SHIFT = 1
34
+ else:
35
+ LOAD_SHIFT = 0
36
+
37
+ if sys.version_info > (3, 11):
38
+ LOAD_SHIFT = 1
39
+ else:
40
+ LOAD_SHIFT = 0
28
41
 
29
42
  NoneType = type(None)
30
43
  EllipsisType = type(Ellipsis)
@@ -441,7 +454,8 @@ class _MissingImportFinder(object):
441
454
  literal_brace_identifiers = set(
442
455
  iden
443
456
  for f in codeblock.string_literals()
444
- for iden in brace_identifiers(f.s))
457
+ for iden in brace_identifiers(getattr(f, ATTRIBUTE_NAME))
458
+ )
445
459
  if literal_brace_identifiers:
446
460
  for ident in literal_brace_identifiers:
447
461
  try:
@@ -450,6 +464,7 @@ class _MissingImportFinder(object):
450
464
  continue
451
465
  symbol_needs_import(ident, self.scopestack)
452
466
  self._scan_unused_imports()
467
+ logger.debug("missing: %s, unused: %s", missing_imports, self.unused_imports)
453
468
  return missing_imports, self.unused_imports
454
469
 
455
470
  def visit(self, node):
@@ -498,11 +513,11 @@ class _MissingImportFinder(object):
498
513
  self.visit(value)
499
514
  else:
500
515
  raise TypeError(
501
- "unexpected %s" %
502
- (', '.join(type(v).__name__ for v in value)))
503
- elif isinstance(value, (six.integer_types, float, complex,
504
- str, six.text_type, NoneType, bytes,
505
- EllipsisType)):
516
+ "unexpected %s" % (", ".join(type(v).__name__ for v in value))
517
+ )
518
+ elif isinstance(
519
+ value, (int, float, complex, str, NoneType, bytes, EllipsisType)
520
+ ):
506
521
  pass
507
522
  else:
508
523
  raise TypeError(
@@ -570,7 +585,7 @@ class _MissingImportFinder(object):
570
585
  if not isinstance(node.value, ast.List):
571
586
  logger.warning("Don't know how to handle __all__ as (%s)" % node.value)
572
587
  return
573
- if not all(isinstance(e, ast.Str) for e in node.value.elts):
588
+ if not all(_is_ast_str(e) for e in node.value.elts):
574
589
  logger.warning("Don't know how to handle __all__ with list elements other than str")
575
590
  return
576
591
  for e in node.value.elts:
@@ -578,7 +593,11 @@ class _MissingImportFinder(object):
578
593
 
579
594
  def visit_ClassDef(self, node):
580
595
  logger.debug("visit_ClassDef(%r)", node)
581
- assert node._fields == ('name', 'bases', 'keywords', 'body', 'decorator_list')
596
+ if sys.version_info > (3,12):
597
+ # we don't visit type_params, so autoimport won't work yet for type annotations
598
+ assert node._fields == ('name', 'bases', 'keywords', 'body', 'decorator_list', 'type_params'), node._fields
599
+ else:
600
+ assert node._fields == ('name', 'bases', 'keywords', 'body', 'decorator_list'), node._fields
582
601
  self.visit(node.bases)
583
602
  self.visit(node.decorator_list)
584
603
  # The class's name is only visible to others (not to the body to the
@@ -609,10 +628,14 @@ class _MissingImportFinder(object):
609
628
  # scope.
610
629
  # - Store the name in the current scope (but not visibly to
611
630
  # args/decorator_list).
612
- assert node._fields == ('name', 'args', 'body', 'decorator_list', 'returns', 'type_comment'), node._fields
631
+ if sys.version_info > (3, 12):
632
+ # we don't visit type_params, so autoimport won't work yet for type annotations
633
+ assert node._fields == ('name', 'args', 'body', 'decorator_list', 'returns', 'type_comment', 'type_params'), node._fields
634
+ else:
635
+ assert node._fields == ('name', 'args', 'body', 'decorator_list', 'returns', 'type_comment'), node._fields
613
636
  with self._NewScopeCtx(include_class_scopes=True):
614
- self.visit(node.args)
615
637
  self.visit(node.decorator_list)
638
+ self.visit(node.args)
616
639
  if node.returns:
617
640
  self.visit(node.returns)
618
641
  self._visit_typecomment(node.type_comment)
@@ -872,6 +895,7 @@ class _MissingImportFinder(object):
872
895
  # record it as unused.
873
896
  oldvalue = scope.get(fullname)
874
897
  if isinstance(oldvalue, _UseChecker) and not oldvalue.used:
898
+ logger.debug("Adding to unused %s", oldvalue)
875
899
  self.unused_imports.append((oldvalue.lineno, oldvalue.source))
876
900
  scope[fullname] = value
877
901
 
@@ -1002,11 +1026,12 @@ class _MissingImportFinder(object):
1002
1026
  if unused_imports is None:
1003
1027
  return
1004
1028
  scope = self.scopestack[-1]
1005
- for name, value in six.iteritems(scope):
1029
+ for name, value in scope.items():
1006
1030
  if not isinstance(value, _UseChecker):
1007
1031
  continue
1008
1032
  if value.used:
1009
1033
  continue
1034
+ logger.debug("Also Adding to usunsed import: %s ", value)
1010
1035
  unused_imports.append(( value.lineno, value.source ))
1011
1036
  unused_imports.sort()
1012
1037
 
@@ -1128,13 +1153,19 @@ def _find_loads_without_stores_in_code(co, loads_without_stores):
1128
1153
  % (type(co).__name__,))
1129
1154
  # Initialize local constants for fast access.
1130
1155
  from opcode import HAVE_ARGUMENT, EXTENDED_ARG, opmap
1156
+
1131
1157
  LOAD_ATTR = opmap['LOAD_ATTR']
1132
- LOAD_METHOD = opmap['LOAD_METHOD']
1158
+ LOAD_METHOD = opmap['LOAD_METHOD']
1133
1159
  LOAD_GLOBAL = opmap['LOAD_GLOBAL']
1134
1160
  LOAD_NAME = opmap['LOAD_NAME']
1135
1161
  STORE_ATTR = opmap['STORE_ATTR']
1136
1162
  STORE_GLOBAL = opmap['STORE_GLOBAL']
1137
1163
  STORE_NAME = opmap['STORE_NAME']
1164
+
1165
+ if sys.version_info > (3, 11):
1166
+ CACHE = opmap["CACHE"]
1167
+ else:
1168
+ CACHE = object()
1138
1169
  # Keep track of the partial name so far that started with a LOAD_GLOBAL.
1139
1170
  # If ``pending`` is not None, then it is a list representing the name
1140
1171
  # components we've seen so far.
@@ -1227,6 +1258,8 @@ def _find_loads_without_stores_in_code(co, loads_without_stores):
1227
1258
  c = bytecode[i]
1228
1259
  op = _op(c)
1229
1260
  i += 1
1261
+ if op == CACHE:
1262
+ continue
1230
1263
  if op >= HAVE_ARGUMENT:
1231
1264
  oparg = bytecode[i] | extended_arg
1232
1265
  extended_arg = 0
@@ -1258,7 +1291,13 @@ def _find_loads_without_stores_in_code(co, loads_without_stores):
1258
1291
  loads_before_label_without_stores.add(fullname)
1259
1292
  # Fall through.
1260
1293
 
1261
- if op in [LOAD_GLOBAL, LOAD_NAME]:
1294
+ if op is LOAD_GLOBAL:
1295
+ # Starting with 3.11, the low bit is used to tell whether to
1296
+ # push an extra null on the stack, so we need to >> 1
1297
+ # >> 0 does nothing
1298
+ pending = [co.co_names[oparg >> LOAD_SHIFT]]
1299
+ continue
1300
+ if op is LOAD_NAME:
1262
1301
  pending = [co.co_names[oparg]]
1263
1302
  continue
1264
1303
 
@@ -1489,7 +1528,7 @@ def find_missing_imports(arg, namespaces):
1489
1528
  ``list`` of ``DottedIdentifier``
1490
1529
  """
1491
1530
  namespaces = ScopeStack(namespaces)
1492
- if isinstance(arg, (DottedIdentifier, six.string_types)):
1531
+ if isinstance(arg, (DottedIdentifier, str)):
1493
1532
  try:
1494
1533
  arg = DottedIdentifier(arg)
1495
1534
  except BadDottedIdentifierError:
@@ -1626,7 +1665,7 @@ def _try_import(imp, namespace):
1626
1665
  # then (3) copy into the user's namespace if it didn't already exist.
1627
1666
  scratch_namespace = {}
1628
1667
  try:
1629
- exec_(stmt, scratch_namespace)
1668
+ exec(stmt, scratch_namespace)
1630
1669
  imported = scratch_namespace[name0]
1631
1670
  except Exception as e:
1632
1671
  logger.warning("Error attempting to %r: %s: %s", stmt, type(e).__name__, e,
@@ -1897,7 +1936,7 @@ def auto_eval(arg, filename=None, mode=None,
1897
1936
  """
1898
1937
  if isinstance(flags, int):
1899
1938
  assert isinstance(flags, CompilerFlags)
1900
- if isinstance(arg, (six.string_types, Filename, FileText, PythonBlock)):
1939
+ if isinstance(arg, (str, Filename, FileText, PythonBlock)):
1901
1940
  block = PythonBlock(arg, filename=filename, flags=flags,
1902
1941
  auto_flags=auto_flags)
1903
1942
  flags = block.flags
@@ -4,7 +4,8 @@ from __future__ import print_function
4
4
  from pyflyby._imports2s import (SourceToSourceFileImportsTransformation,
5
5
  SourceToSourceImportBlockTransformation,
6
6
  fix_unused_and_missing_imports,
7
- replace_star_imports)
7
+ replace_star_imports,
8
+ reformat_import_statements)
8
9
  from pyflyby._importstmt import Import
9
10
  from pyflyby._log import logger
10
11
  import six
@@ -92,8 +93,6 @@ def comm_close_handler(comm, message):
92
93
 
93
94
 
94
95
  def _reformat_helper(input_code, imports):
95
- from pyflyby._imports2s import reformat_import_statements
96
-
97
96
  if PYFLYBY_START_MSG in input_code:
98
97
  before, bmarker, middle = input_code.partition(PYFLYBY_START_MSG)
99
98
  else:
@@ -131,8 +130,8 @@ def extract_import_statements(text):
131
130
  extracting the import statements.
132
131
  """
133
132
  transformer = SourceToSourceFileImportsTransformation(text)
134
- imports = '\n'.join([str(im.pretty_print()) for im in transformer.import_blocks])
135
- remaining_code = "\n".join([str(st.pretty_print()) if not isinstance(st, SourceToSourceImportBlockTransformation) else "" for st in transformer.blocks])
133
+ imports = '\n'.join([str(im.pretty_print()).strip() for im in transformer.import_blocks])
134
+ remaining_code = "\n".join([str(st.pretty_print()).strip() if not isinstance(st, SourceToSourceImportBlockTransformation) else "" for st in transformer.blocks])
136
135
  return imports, remaining_code
137
136
 
138
137
  def collect_code_with_imports_on_top(imports: str, cell_array):
@@ -141,16 +140,18 @@ def collect_code_with_imports_on_top(imports: str, cell_array):
141
140
  + "\n"
142
141
  + "\n".join(
143
142
  [
144
- cell["text"] if cell["type"] == "code" else ""
143
+ cell["text"] if cell["type"] == "code" and not cell.get("ignore", False) else ""
145
144
  for cell in cell_array
146
145
  ]
147
146
  )
148
147
  )
149
148
 
150
149
  def run_tidy_imports(code):
151
- return str(
152
- fix_unused_and_missing_imports(
153
- replace_star_imports(code)
150
+ return str(
151
+ reformat_import_statements(
152
+ fix_unused_and_missing_imports(
153
+ replace_star_imports(code)
154
+ )
154
155
  )
155
156
  )
156
157
 
@@ -192,12 +193,20 @@ def comm_open_handler(comm, message):
192
193
  # while clubbing similar imports and re-ordering them.
193
194
  import_statements, processed_cell_array = "", []
194
195
  for cell in cell_array:
196
+ ignore = False
195
197
  text = cell.get("text")
196
198
  cell_type = cell.get("type")
197
199
  if cell_type == "code":
198
- imports, text = extract_import_statements(text)
199
- import_statements += imports
200
- processed_cell_array.append({"text": text, "type": cell_type})
200
+ try:
201
+ imports, text = extract_import_statements(text)
202
+ import_statements += (imports + "\n")
203
+ except SyntaxError:
204
+ # If a cell triggers Syntax Error, we set ignore to
205
+ # True and don't include it when running tidy-imports
206
+ # For eg. this is triggered due to cells with magic
207
+ # commands
208
+ ignore = True
209
+ processed_cell_array.append({"text": text, "type": cell_type, "ignore": ignore})
201
210
  code_with_collected_imports = collect_code_with_imports_on_top(import_statements, processed_cell_array)
202
211
  code_post_tidy_imports = run_tidy_imports(code_with_collected_imports)
203
212
  import_statements, _ = extract_import_statements(code_post_tidy_imports)
@@ -3,7 +3,7 @@
3
3
  # License: MIT http://opensource.org/licenses/MIT
4
4
 
5
5
 
6
-
6
+ import builtins
7
7
  from contextlib import contextmanager
8
8
  import errno
9
9
  from functools import wraps
@@ -14,9 +14,6 @@ import sys
14
14
  import time
15
15
  from types import CodeType, FrameType, TracebackType
16
16
 
17
- import six
18
- from six.moves import builtins
19
-
20
17
  from collections.abc import Callable
21
18
 
22
19
  from pyflyby._file import Filename
@@ -349,7 +346,8 @@ def _debug_code(arg, globals=None, locals=None, auto_import=True, tty="/dev/tty"
349
346
  print("Entering debugger. Use 'n' to step, 'c' to run, 'q' to stop.")
350
347
  print("")
351
348
  from ._parse import PythonStatement, PythonBlock, FileText
352
- if isinstance(arg, (six.string_types, PythonStatement, PythonBlock, FileText)):
349
+
350
+ if isinstance(arg, (str, PythonStatement, PythonBlock, FileText)):
353
351
  # Compile the block so that we can get the right compile mode.
354
352
  arg = PythonBlock(arg)
355
353
  # TODO: enter text into linecache
@@ -502,8 +500,9 @@ def debugger(*args, **kwargs):
502
500
  # TODO: capture globals/locals when relevant.
503
501
  wait_for_debugger_to_attach(arg)
504
502
  return
505
- if isinstance(arg, (six.string_types, PythonStatement, PythonBlock, FileText,
506
- CodeType, Callable)):
503
+ if isinstance(
504
+ arg, (str, PythonStatement, PythonBlock, FileText, CodeType, Callable)
505
+ ):
507
506
  _debug_code(arg, globals=globals, locals=locals, tty=tty)
508
507
  on_continue()
509
508
  return
@@ -1013,12 +1012,12 @@ def inject(pid, statements, wait=True, show_gdb_output=False):
1013
1012
  """
1014
1013
  import subprocess
1015
1014
  os.kill(pid, 0) # raises OSError "No such process" unless pid exists
1016
- if isinstance(statements, six.string_types):
1015
+ if isinstance(statements, str):
1017
1016
  statements = (statements,)
1018
1017
  else:
1019
1018
  statements = tuple(statements)
1020
1019
  for statement in statements:
1021
- if not isinstance(statement, six.string_types):
1020
+ if not isinstance(statement, str):
1022
1021
  raise TypeError(
1023
1022
  "Expected iterable of strings, not %r" % (type(statement),))
1024
1023
  # Based on
@@ -26,8 +26,7 @@
26
26
 
27
27
 
28
28
  import re
29
- import six
30
- from six.moves import builtins
29
+ import builtins
31
30
  from textwrap import dedent
32
31
 
33
32
  from epydoc.apidoc import (ClassDoc, ModuleDoc, PropertyDoc,
@@ -348,7 +347,7 @@ class XrefScanner(object):
348
347
  return ''
349
348
 
350
349
  def scan_tree(tree):
351
- if isinstance(tree, six.string_types):
350
+ if isinstance(tree, str):
352
351
  return tree
353
352
  variables = [scan_tree(child) for child in tree.children]
354
353
  if tree.tag == 'link':
@@ -8,11 +8,8 @@ from functools import total_ordering
8
8
  import io
9
9
  import os
10
10
  import re
11
- import six
12
11
  import sys
13
12
 
14
- from six import string_types
15
-
16
13
  from pyflyby._util import cached_attribute, cmp, memoize
17
14
 
18
15
 
@@ -34,13 +31,13 @@ class Filename(object):
34
31
  def __new__(cls, arg):
35
32
  if isinstance(arg, cls):
36
33
  return arg
37
- if isinstance(arg, six.string_types):
34
+ if isinstance(arg, str):
38
35
  return cls._from_filename(arg)
39
36
  raise TypeError
40
37
 
41
38
  @classmethod
42
39
  def _from_filename(cls, filename):
43
- if not isinstance(filename, six.string_types):
40
+ if not isinstance(filename, str):
44
41
  raise TypeError
45
42
  filename = str(filename)
46
43
  if not filename:
@@ -336,7 +333,7 @@ FilePos._ONE_ONE = FilePos._from_lc(1, 1)
336
333
 
337
334
 
338
335
  @total_ordering
339
- class FileText(object):
336
+ class FileText:
340
337
  """
341
338
  Represents a contiguous sequence of lines from a file.
342
339
  """
@@ -372,7 +369,7 @@ class FileText(object):
372
369
  return cls(read_file(arg), filename=filename, startpos=startpos)
373
370
  elif hasattr(arg, "__text__"):
374
371
  return FileText(arg.__text__(), filename=filename, startpos=startpos)
375
- elif isinstance(arg, six.string_types):
372
+ elif isinstance(arg, str):
376
373
  self = object.__new__(cls)
377
374
  self.joined = arg
378
375
  else:
@@ -389,7 +386,7 @@ class FileText(object):
389
386
  def _from_lines(cls, lines, filename, startpos):
390
387
  assert type(lines) is tuple
391
388
  assert len(lines) > 0
392
- assert isinstance(lines[0], string_types)
389
+ assert isinstance(lines[0], str)
393
390
  assert not lines[-1].endswith("\n")
394
391
  self = object.__new__(cls)
395
392
  self.lines = lines
@@ -7,11 +7,11 @@
7
7
  import __future__
8
8
  import ast
9
9
  import operator
10
- import six
11
10
  from six.moves import reduce
12
11
  import warnings
13
12
 
14
13
  from pyflyby._util import cached_attribute
14
+ from typing import Tuple
15
15
 
16
16
  # Initialize mappings from compiler_flag to feature name and vice versa.
17
17
  _FLAG2NAME = {}
@@ -49,6 +49,10 @@ class CompilerFlags(int):
49
49
 
50
50
  """
51
51
 
52
+ # technically both those are compiler flags, but we can't use Self. May need typing_extensions ?
53
+ _ZERO:int
54
+ _UNKNOWN: int
55
+
52
56
  def __new__(cls, *args):
53
57
  """
54
58
  Construct a new ``CompilerFlags`` instance.
@@ -72,7 +76,7 @@ class CompilerFlags(int):
72
76
  ' flags values change between Python versions. If you are sure use .from_int',
73
77
  DeprecationWarning, stacklevel=2)
74
78
  return cls.from_int(arg)
75
- elif isinstance(arg, six.string_types):
79
+ elif isinstance(arg, str):
76
80
  return cls.from_str(arg)
77
81
  elif isinstance(arg, ast.AST):
78
82
  return cls.from_ast(arg)
@@ -100,7 +104,7 @@ class CompilerFlags(int):
100
104
  raise ValueError
101
105
 
102
106
  #assert flags == [0x10000, 0x8000], flags
103
-
107
+
104
108
  return cls.from_int(reduce(operator.or_, flags))
105
109
 
106
110
  @classmethod
@@ -117,7 +121,7 @@ class CompilerFlags(int):
117
121
  return self
118
122
 
119
123
  @classmethod
120
- def from_str(cls, arg):
124
+ def from_str(cls, arg:str):
121
125
  try:
122
126
  flag = _NAME2FLAG[arg]
123
127
  except KeyError:
@@ -153,7 +157,7 @@ class CompilerFlags(int):
153
157
  return cls(flags)
154
158
 
155
159
  @cached_attribute
156
- def names(self):
160
+ def names(self) -> Tuple[str]:
157
161
  return tuple(
158
162
  n
159
163
  for f, n in _FLAGNAME_ITEMS
@@ -4,9 +4,6 @@
4
4
 
5
5
 
6
6
 
7
- import six
8
-
9
-
10
7
  class FormatParams(object):
11
8
  max_line_length = None
12
9
  _max_line_lenght_default = 79
@@ -24,14 +21,16 @@ class FormatParams(object):
24
21
  for arg in args:
25
22
  if arg is None:
26
23
  pass
27
- elif isinstance(arg, cls):
24
+ elif isinstance(arg, cls) or hasattr(self, "__dict__"):
28
25
  dicts.append(arg.__dict__)
29
26
  else:
30
- raise TypeError
27
+ raise TypeError(
28
+ "expected None, or instance of %s cls, got %s" % (cls, arg)
29
+ )
31
30
  if kwargs:
32
31
  dicts.append(kwargs)
33
32
  for kwargs in dicts:
34
- for key, value in six.iteritems(kwargs):
33
+ for key, value in kwargs.items():
35
34
  if hasattr(self, key):
36
35
  setattr(self, key, value)
37
36
  else:
@@ -7,10 +7,11 @@
7
7
  from functools import total_ordering
8
8
  from keyword import kwlist
9
9
  import re
10
- import six
11
10
 
12
11
  from pyflyby._util import cached_attribute, cmp
13
12
 
13
+ from typing import Optional, Tuple, Dict
14
+
14
15
 
15
16
  # Don't consider "print" a keyword, in order to be compatible with user code
16
17
  # that uses "from __future__ import print_function".
@@ -46,12 +47,7 @@ def dotted_prefixes(dotted_name, reverse=False):
46
47
  return result
47
48
 
48
49
 
49
- _name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$")
50
- _dotted_name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*([.][a-zA-Z_][a-zA-Z0-9_]*)*$")
51
- _dotted_name_prefix_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*([.][a-zA-Z_][a-zA-Z0-9_]*)*[.]?$")
52
-
53
-
54
- def is_identifier(s, dotted=False, prefix=False):
50
+ def is_identifier(s: str, dotted: bool = False, prefix: bool = False):
55
51
  """
56
52
  Return whether ``s`` is a valid Python identifier name.
57
53
 
@@ -111,7 +107,7 @@ def is_identifier(s, dotted=False, prefix=False):
111
107
  :rtype:
112
108
  ``bool``
113
109
  """
114
- if not isinstance(s, six.string_types):
110
+ if not isinstance(s, str):
115
111
  raise TypeError("is_identifier(): expected a string; got a %s"
116
112
  % (type(s).__name__,))
117
113
  if prefix:
@@ -140,11 +136,15 @@ class BadDottedIdentifierError(ValueError):
140
136
 
141
137
  # TODO: Use in various places, esp where e.g. dotted_prefixes is used.
142
138
  @total_ordering
143
- class DottedIdentifier(object):
139
+ class DottedIdentifier:
140
+ name: str
141
+ parts: Tuple[str, ...]
142
+ scope_info: Optional[Dict]
143
+
144
144
  def __new__(cls, arg, scope_info=None):
145
145
  if isinstance(arg, cls):
146
146
  return arg
147
- if isinstance(arg, six.string_types):
147
+ if isinstance(arg, str):
148
148
  return cls._from_name(arg, scope_info)
149
149
  if isinstance(arg, (tuple, list)):
150
150
  return cls._from_name(".".join(arg), scope_info)
@@ -17,6 +17,8 @@ from pyflyby._parse import PythonBlock
17
17
  from pyflyby._util import (cached_attribute, cmp, partition,
18
18
  stable_unique)
19
19
 
20
+ from typing import Dict
21
+
20
22
 
21
23
  class NoSuchImportError(ValueError):
22
24
  pass
@@ -213,8 +215,8 @@ class ImportSet(object):
213
215
  """
214
216
  :return:
215
217
  (mapping from name to __future__ imports,
216
- mapping from name to non-'from' imports,
217
- mapping from name to 'from' imports)
218
+ mapping from name to non-'from' imports,
219
+ mapping from name to 'from' imports)
218
220
  """
219
221
  ftr_imports = defaultdict(set)
220
222
  pkg_imports = defaultdict(set)
@@ -228,9 +230,9 @@ class ImportSet(object):
228
230
  else:
229
231
  frm_imports[module_name].add(imp)
230
232
  return tuple(
231
- dict( (k, frozenset(v))
232
- for k, v in six.iteritems(imports))
233
- for imports in [ftr_imports, pkg_imports, frm_imports])
233
+ dict((k, frozenset(v)) for k, v in imports.items())
234
+ for imports in [ftr_imports, pkg_imports, frm_imports]
235
+ )
234
236
 
235
237
  def get_statements(self, separate_from_imports=True):
236
238
  """
@@ -261,8 +263,8 @@ class ImportSet(object):
261
263
  if not separate_from_imports:
262
264
  def union_dicts(*dicts):
263
265
  result = {}
264
- for label, dict in enumerate(dicts):
265
- for k, v in six.iteritems(dict):
266
+ for label, dct in enumerate(dicts):
267
+ for k, v in dct.items():
266
268
  result[(k, label)] = v
267
269
  return result
268
270
  groups = [groups[0], union_dicts(*groups[1:])]
@@ -317,8 +319,7 @@ class ImportSet(object):
317
319
  d = defaultdict(list)
318
320
  for imp in self._importset:
319
321
  d[imp.import_as].append(imp)
320
- return dict( (k, tuple(sorted(stable_unique(v))))
321
- for k, v in six.iteritems(d) )
322
+ return dict((k, tuple(sorted(stable_unique(v)))) for k, v in d.items())
322
323
 
323
324
  @cached_attribute
324
325
  def member_names(self):
@@ -347,8 +348,7 @@ class ImportSet(object):
347
348
  for prefix in prefixes[1:]:
348
349
  splt = prefix.rsplit(".", 1)
349
350
  d[splt[0]].add(splt[1])
350
- return dict( (k, tuple(sorted(v)))
351
- for k, v in six.iteritems(d) )
351
+ return dict((k, tuple(sorted(v))) for k, v in d.items())
352
352
 
353
353
  @cached_attribute
354
354
  def conflicting_imports(self):
@@ -364,10 +364,7 @@ class ImportSet(object):
364
364
  :rtype:
365
365
  ``bool``
366
366
  """
367
- return tuple(
368
- k
369
- for k, v in six.iteritems(self.by_import_as)
370
- if len(v) > 1 and k != "*")
367
+ return tuple(k for k, v in self.by_import_as.items() if len(v) > 1 and k != "*")
371
368
 
372
369
  @cached_attribute
373
370
  def flags(self):
@@ -522,6 +519,8 @@ class ImportMap(object):
522
519
  An ``ImportMap`` is an immutable data structure.
523
520
  """
524
521
 
522
+ _data: Dict
523
+
525
524
  def __new__(cls, arg):
526
525
  if isinstance(arg, cls):
527
526
  return arg
@@ -565,7 +564,7 @@ class ImportMap(object):
565
564
  return self._data.items()
566
565
 
567
566
  def iteritems(self):
568
- return six.iteritems(self._data)
567
+ return self._data.items()
569
568
 
570
569
  def iterkeys(self):
571
570
  return six.iterkeys(self._data)