pyflyby 1.9.7__tar.gz → 1.9.9__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.
- {pyflyby-1.9.7/lib/python/pyflyby.egg-info → pyflyby-1.9.9}/PKG-INFO +11 -11
- {pyflyby-1.9.7 → pyflyby-1.9.9}/README.rst +9 -9
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/pyflyby/_autoimp.py +98 -38
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/pyflyby/_dbg.py +8 -0
- {pyflyby-1.9.7/lib/python → pyflyby-1.9.9/bin}/pyflyby/_dynimp.py +3 -2
- {pyflyby-1.9.7/lib/python → pyflyby-1.9.9/bin}/pyflyby/_importdb.py +8 -4
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/pyflyby/_imports2s.py +10 -9
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/pyflyby/_importstmt.py +1 -1
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/pyflyby/_interactive.py +20 -202
- {pyflyby-1.9.7/lib/python → pyflyby-1.9.9/bin}/pyflyby/_parse.py +27 -94
- {pyflyby-1.9.7/lib/python → pyflyby-1.9.9/bin}/pyflyby/_py.py +18 -18
- {pyflyby-1.9.7/lib/python → pyflyby-1.9.9/bin}/pyflyby/_saveframe.py +1 -1
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/pyflyby/_util.py +1 -2
- {pyflyby-1.9.7/lib/python → pyflyby-1.9.9/bin}/pyflyby/_version.py +1 -1
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/saveframe +2 -2
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby/_autoimp.py +98 -38
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby/_dbg.py +8 -0
- {pyflyby-1.9.7/bin → pyflyby-1.9.9/lib/python}/pyflyby/_dynimp.py +3 -2
- {pyflyby-1.9.7/bin → pyflyby-1.9.9/lib/python}/pyflyby/_importdb.py +8 -4
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby/_imports2s.py +10 -9
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby/_importstmt.py +1 -1
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby/_interactive.py +20 -202
- {pyflyby-1.9.7/bin → pyflyby-1.9.9/lib/python}/pyflyby/_parse.py +27 -94
- {pyflyby-1.9.7/bin → pyflyby-1.9.9/lib/python}/pyflyby/_py.py +18 -18
- {pyflyby-1.9.7/bin → pyflyby-1.9.9/lib/python}/pyflyby/_saveframe.py +1 -1
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby/_util.py +1 -2
- {pyflyby-1.9.7/bin → pyflyby-1.9.9/lib/python}/pyflyby/_version.py +1 -1
- {pyflyby-1.9.7 → pyflyby-1.9.9/lib/python/pyflyby.egg-info}/PKG-INFO +11 -11
- {pyflyby-1.9.7 → pyflyby-1.9.9}/setup.py +1 -1
- {pyflyby-1.9.7 → pyflyby-1.9.9}/tests/test_autoimp.py +11 -1
- {pyflyby-1.9.7 → pyflyby-1.9.9}/tests/test_modules.py +3 -1
- {pyflyby-1.9.7 → pyflyby-1.9.9}/tests/test_parse.py +36 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/.pyflyby +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/LICENSE.txt +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/MANIFEST.in +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/autoipython +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/autopython +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/collect-exports +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/collect-imports +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/create-imports +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/find-import +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/list-bad-xrefs +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/prune-broken-imports +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/pyflyby/__init__.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/pyflyby/__main__.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/pyflyby/_cmdline.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/pyflyby/_comms.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/pyflyby/_docxref.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/pyflyby/_file.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/pyflyby/_flags.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/pyflyby/_format.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/pyflyby/_idents.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/pyflyby/_import_sorting.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/pyflyby/_importclns.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/pyflyby/_livepatch.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/pyflyby/_log.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/pyflyby/_modules.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/pyflyby/autoimport.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/pyflyby/importdb.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/pyflyby-diff +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/reformat-imports +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/replace-star-imports +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/tidy-imports +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/bin/transform-imports +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/LICENSE.txt +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/Makefile +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/TODO.txt +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/__init__.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/api/api.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/api/autoimp.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/api/cmdline.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/api/comms.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/api/dbg.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/api/file.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/api/flags.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/api/format.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/api/idents.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/api/importclns.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/api/importdb.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/api/imports2s.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/api/importstmt.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/api/interactive.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/api/livepatch.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/api/log.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/api/modules.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/api/parse.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/api/py.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/api/util.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/cli/autoipython.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/cli/cli.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/cli/collect_exports.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/cli/collect_imports.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/cli/find_import.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/cli/prune_broken_imports.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/cli/py.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/cli/pyflyby_diff.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/cli/reformat_imports.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/cli/replace_star_imports.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/cli/tidy_imports.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/cli/transform_imports.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/conf.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/index.rst +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/make.bat +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/doc/testing.txt +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/etc/pyflyby/canonical.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/etc/pyflyby/common.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/etc/pyflyby/forget.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/etc/pyflyby/mandatory.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/etc/pyflyby/numpy.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/etc/pyflyby/std.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/emacs/pyflyby.el +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby/__init__.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby/__main__.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby/_cmdline.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby/_comms.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby/_docxref.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby/_file.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby/_flags.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby/_format.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby/_idents.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby/_import_sorting.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby/_importclns.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby/_livepatch.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby/_log.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby/_modules.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby/autoimport.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby/importdb.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby.egg-info/SOURCES.txt +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby.egg-info/dependency_links.txt +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby.egg-info/entry_points.txt +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby.egg-info/requires.txt +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/lib/python/pyflyby.egg-info/top_level.txt +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/libexec/pyflyby/colordiff +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/libexec/pyflyby/diff-colorize +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/pyproject.toml +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/setup.cfg +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/tests/__init__.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/tests/test_0testconfig.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/tests/test_cmdline.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/tests/test_docxref.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/tests/test_file.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/tests/test_flags.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/tests/test_format.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/tests/test_idents.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/tests/test_importclns.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/tests/test_importdb.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/tests/test_imports2s.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/tests/test_importstmt.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/tests/test_interactive.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/tests/test_jupyterlab_pyflyby.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/tests/test_livepatch.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/tests/test_py.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/tests/test_saveframe.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/tests/test_util.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/tests/tests_sorts.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/tests/xrefs.py +0 -0
- {pyflyby-1.9.7 → pyflyby-1.9.9}/tox.ini +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pyflyby
|
|
3
|
-
Version: 1.9.
|
|
3
|
+
Version: 1.9.9
|
|
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
|
|
@@ -16,7 +16,7 @@ Classifier: Topic :: Software Development :: Interpreters
|
|
|
16
16
|
Classifier: Intended Audience :: Developers
|
|
17
17
|
Classifier: License :: OSI Approved :: MIT License
|
|
18
18
|
Classifier: Programming Language :: Python
|
|
19
|
-
Requires-Python: >3.
|
|
19
|
+
Requires-Python: >3.9, <4
|
|
20
20
|
License-File: LICENSE.txt
|
|
21
21
|
|
|
22
22
|
#########
|
|
@@ -113,7 +113,7 @@ configuration file:
|
|
|
113
113
|
|
|
114
114
|
.. code:: python
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
|
|
117
117
|
from pyflyby import add_import
|
|
118
118
|
|
|
119
119
|
add_import("foo", "foo = 1")
|
|
@@ -484,29 +484,29 @@ Emacs support
|
|
|
484
484
|
saveframe: A utility for debugging / reproducing an issue
|
|
485
485
|
=========================================================
|
|
486
486
|
|
|
487
|
-
PyFlyBy provides a utility named **saveframe** which can be used to save
|
|
487
|
+
PyFlyBy provides a utility named **saveframe** which can be used to save
|
|
488
488
|
information for debugging / reproducing an issue.
|
|
489
489
|
|
|
490
|
-
**Usage**: If you have a piece of code or a script that is failing due an issue
|
|
491
|
-
originating from upstream code, and you cannot share your private code as a reproducer,
|
|
492
|
-
use this utility to save relevant information to a file. Share the generated file with
|
|
490
|
+
**Usage**: If you have a piece of code or a script that is failing due an issue
|
|
491
|
+
originating from upstream code, and you cannot share your private code as a reproducer,
|
|
492
|
+
use this utility to save relevant information to a file. Share the generated file with
|
|
493
493
|
the upstream team, enabling them to reproduce and diagnose the issue independently.
|
|
494
494
|
|
|
495
|
-
**Information saved in the file**: This utility captures and saves *error stack frames*
|
|
496
|
-
to a file. It includes the values of local variables from each stack frame, as well
|
|
495
|
+
**Information saved in the file**: This utility captures and saves *error stack frames*
|
|
496
|
+
to a file. It includes the values of local variables from each stack frame, as well
|
|
497
497
|
as metadata about each frame and the exception raised by your code.
|
|
498
498
|
|
|
499
499
|
This utility comes with 2 interfaces:
|
|
500
500
|
|
|
501
501
|
1. **A function**: For interactive usages such as IPython, Jupyter Notebook, or a
|
|
502
|
-
debugger (pdb/ipdb), use **pyflyby.saveframe** function. To know how to use this
|
|
502
|
+
debugger (pdb/ipdb), use **pyflyby.saveframe** function. To know how to use this
|
|
503
503
|
function, checkout it's documentation:
|
|
504
504
|
|
|
505
505
|
.. code::
|
|
506
506
|
|
|
507
507
|
In [1]: saveframe?
|
|
508
508
|
|
|
509
|
-
2. **A script**: For cli usages (like a failing script), use **pyflyby/bin/saveframe**
|
|
509
|
+
2. **A script**: For cli usages (like a failing script), use **pyflyby/bin/saveframe**
|
|
510
510
|
script. To know how to use this script, checkout its documentation:
|
|
511
511
|
|
|
512
512
|
.. code::
|
|
@@ -92,7 +92,7 @@ configuration file:
|
|
|
92
92
|
|
|
93
93
|
.. code:: python
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
|
|
96
96
|
from pyflyby import add_import
|
|
97
97
|
|
|
98
98
|
add_import("foo", "foo = 1")
|
|
@@ -463,29 +463,29 @@ Emacs support
|
|
|
463
463
|
saveframe: A utility for debugging / reproducing an issue
|
|
464
464
|
=========================================================
|
|
465
465
|
|
|
466
|
-
PyFlyBy provides a utility named **saveframe** which can be used to save
|
|
466
|
+
PyFlyBy provides a utility named **saveframe** which can be used to save
|
|
467
467
|
information for debugging / reproducing an issue.
|
|
468
468
|
|
|
469
|
-
**Usage**: If you have a piece of code or a script that is failing due an issue
|
|
470
|
-
originating from upstream code, and you cannot share your private code as a reproducer,
|
|
471
|
-
use this utility to save relevant information to a file. Share the generated file with
|
|
469
|
+
**Usage**: If you have a piece of code or a script that is failing due an issue
|
|
470
|
+
originating from upstream code, and you cannot share your private code as a reproducer,
|
|
471
|
+
use this utility to save relevant information to a file. Share the generated file with
|
|
472
472
|
the upstream team, enabling them to reproduce and diagnose the issue independently.
|
|
473
473
|
|
|
474
|
-
**Information saved in the file**: This utility captures and saves *error stack frames*
|
|
475
|
-
to a file. It includes the values of local variables from each stack frame, as well
|
|
474
|
+
**Information saved in the file**: This utility captures and saves *error stack frames*
|
|
475
|
+
to a file. It includes the values of local variables from each stack frame, as well
|
|
476
476
|
as metadata about each frame and the exception raised by your code.
|
|
477
477
|
|
|
478
478
|
This utility comes with 2 interfaces:
|
|
479
479
|
|
|
480
480
|
1. **A function**: For interactive usages such as IPython, Jupyter Notebook, or a
|
|
481
|
-
debugger (pdb/ipdb), use **pyflyby.saveframe** function. To know how to use this
|
|
481
|
+
debugger (pdb/ipdb), use **pyflyby.saveframe** function. To know how to use this
|
|
482
482
|
function, checkout it's documentation:
|
|
483
483
|
|
|
484
484
|
.. code::
|
|
485
485
|
|
|
486
486
|
In [1]: saveframe?
|
|
487
487
|
|
|
488
|
-
2. **A script**: For cli usages (like a failing script), use **pyflyby/bin/saveframe**
|
|
488
|
+
2. **A script**: For cli usages (like a failing script), use **pyflyby/bin/saveframe**
|
|
489
489
|
script. To know how to use this script, checkout its documentation:
|
|
490
490
|
|
|
491
491
|
.. code::
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
# pyflyby/_autoimp.py.
|
|
2
|
-
# Copyright (C) 2011, 2012, 2013, 2014, 2015, 2018, 2019 Karl Chen.
|
|
2
|
+
# Copyright (C) 2011, 2012, 2013, 2014, 2015, 2018, 2019, 2024 Karl Chen.
|
|
3
3
|
# License: MIT http://opensource.org/licenses/MIT
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
from __future__ import annotations, print_function
|
|
8
|
+
|
|
7
9
|
import ast
|
|
8
10
|
import builtins
|
|
9
11
|
from collections.abc import Sequence
|
|
@@ -18,13 +20,14 @@ from pyflyby._importdb import ImportDB
|
|
|
18
20
|
from pyflyby._importstmt import Import
|
|
19
21
|
from pyflyby._log import logger
|
|
20
22
|
from pyflyby._modules import ModuleHandle
|
|
21
|
-
from pyflyby._parse import (PythonBlock, _is_ast_str,
|
|
22
|
-
infer_compile_mode
|
|
23
|
+
from pyflyby._parse import (MatchAs, PythonBlock, _is_ast_str,
|
|
24
|
+
infer_compile_mode)
|
|
23
25
|
|
|
24
26
|
from six import reraise
|
|
25
27
|
import sys
|
|
26
28
|
import types
|
|
27
|
-
from typing import Any, Set
|
|
29
|
+
from typing import (Any, Dict, List, Optional, Set, Tuple,
|
|
30
|
+
Union)
|
|
28
31
|
|
|
29
32
|
if sys.version_info >= (3, 12):
|
|
30
33
|
ATTRIBUTE_NAME = "value"
|
|
@@ -130,9 +133,13 @@ class ScopeStack(Sequence):
|
|
|
130
133
|
def __len__(self):
|
|
131
134
|
return len(self._tup)
|
|
132
135
|
|
|
133
|
-
def
|
|
134
|
-
self,
|
|
135
|
-
|
|
136
|
+
def _with_new_scope(
|
|
137
|
+
self,
|
|
138
|
+
*,
|
|
139
|
+
include_class_scopes: bool,
|
|
140
|
+
new_class_scope: bool,
|
|
141
|
+
unhide_classdef: bool,
|
|
142
|
+
) -> ScopeStack:
|
|
136
143
|
"""
|
|
137
144
|
Return a new ``ScopeStack`` with an additional empty scope.
|
|
138
145
|
|
|
@@ -148,8 +155,8 @@ class ScopeStack(Sequence):
|
|
|
148
155
|
if include_class_scopes:
|
|
149
156
|
scopes = tuple(self)
|
|
150
157
|
else:
|
|
151
|
-
scopes = tuple(s for s in self
|
|
152
|
-
|
|
158
|
+
scopes = tuple(s for s in self if not isinstance(s, _ClassScope))
|
|
159
|
+
new_scope: Union[_ClassScope, Dict[str, Any]]
|
|
153
160
|
if new_class_scope:
|
|
154
161
|
new_scope = _ClassScope()
|
|
155
162
|
else:
|
|
@@ -199,7 +206,7 @@ class ScopeStack(Sequence):
|
|
|
199
206
|
return (d, self[-1])
|
|
200
207
|
|
|
201
208
|
|
|
202
|
-
def has_star_import(self):
|
|
209
|
+
def has_star_import(self) -> bool:
|
|
203
210
|
"""
|
|
204
211
|
Return whether there are any star-imports in this ScopeStack.
|
|
205
212
|
Only relevant in AST-based static analysis mode.
|
|
@@ -341,19 +348,27 @@ def symbol_needs_import(fullname, namespaces):
|
|
|
341
348
|
return True
|
|
342
349
|
|
|
343
350
|
|
|
344
|
-
class _UseChecker
|
|
351
|
+
class _UseChecker:
|
|
345
352
|
"""
|
|
346
353
|
An object that can check whether it was used.
|
|
347
354
|
"""
|
|
348
|
-
used = False
|
|
349
355
|
|
|
350
|
-
|
|
356
|
+
used: bool = False
|
|
357
|
+
name: str
|
|
358
|
+
source: str
|
|
359
|
+
lineno: int
|
|
360
|
+
|
|
361
|
+
def __init__(self, name: str, source: str, lineno: int):
|
|
351
362
|
self.name = name
|
|
352
363
|
self.source = source # generally an Import
|
|
353
364
|
self.lineno = lineno
|
|
365
|
+
logger.debug("Create _UseChecker : %r", self)
|
|
366
|
+
|
|
367
|
+
def __repr__(self):
|
|
368
|
+
return f"<{type(self).__name__}: name:{self.name!r} source:{self.source!r} lineno:{self.lineno} used:{self.used}>"
|
|
354
369
|
|
|
355
370
|
|
|
356
|
-
class _MissingImportFinder
|
|
371
|
+
class _MissingImportFinder:
|
|
357
372
|
"""
|
|
358
373
|
A helper class to be used only by `_find_missing_imports_in_ast`.
|
|
359
374
|
|
|
@@ -371,8 +386,14 @@ class _MissingImportFinder(object):
|
|
|
371
386
|
|
|
372
387
|
"""
|
|
373
388
|
|
|
374
|
-
|
|
375
|
-
|
|
389
|
+
scopestack: ScopeStack
|
|
390
|
+
_lineno: Optional[int]
|
|
391
|
+
missing_imports: List[Tuple[Optional[int], DottedIdentifier]]
|
|
392
|
+
parse_docstrings: bool
|
|
393
|
+
unused_imports: Optional[List[Tuple[int, str]]]
|
|
394
|
+
_deferred_load_checks: list[tuple[str, ScopeStack, Optional[int]]]
|
|
395
|
+
|
|
396
|
+
def __init__(self, scopestack, *, find_unused_imports:bool, parse_docstrings:bool):
|
|
376
397
|
"""
|
|
377
398
|
Construct the AST visitor.
|
|
378
399
|
|
|
@@ -384,20 +405,27 @@ class _MissingImportFinder(object):
|
|
|
384
405
|
# Create a stack of namespaces. The caller should pass in a list that
|
|
385
406
|
# includes the globals dictionary. ScopeStack() will make sure this
|
|
386
407
|
# includes builtins.
|
|
387
|
-
|
|
408
|
+
_scopestack = ScopeStack(scopestack)
|
|
409
|
+
|
|
388
410
|
# Add an empty namespace to the stack. This facilitates adding stuff
|
|
389
411
|
# to scopestack[-1] without ever modifying user globals.
|
|
390
|
-
scopestack =
|
|
391
|
-
|
|
412
|
+
self.scopestack = _scopestack._with_new_scope(
|
|
413
|
+
include_class_scopes=False, new_class_scope=False, unhide_classdef=False
|
|
414
|
+
)
|
|
415
|
+
|
|
392
416
|
# Create data structure to hold the result.
|
|
393
417
|
# missing_imports is a list of (lineno, DottedIdentifier) tuples.
|
|
394
418
|
self.missing_imports = []
|
|
419
|
+
|
|
395
420
|
# unused_imports is a list of (lineno, Import) tuples, if enabled.
|
|
396
421
|
self.unused_imports = [] if find_unused_imports else None
|
|
422
|
+
|
|
397
423
|
self.parse_docstrings = parse_docstrings
|
|
424
|
+
|
|
398
425
|
# Function bodies that we need to check after defining names in this
|
|
399
426
|
# function scope.
|
|
400
427
|
self._deferred_load_checks = []
|
|
428
|
+
|
|
401
429
|
# Whether we're currently in a FunctionDef.
|
|
402
430
|
self._in_FunctionDef = False
|
|
403
431
|
# Current lineno.
|
|
@@ -419,7 +447,8 @@ class _MissingImportFinder(object):
|
|
|
419
447
|
finally:
|
|
420
448
|
self.scopestack = oldscopestack
|
|
421
449
|
|
|
422
|
-
def scan_for_import_issues(self, codeblock):
|
|
450
|
+
def scan_for_import_issues(self, codeblock: PythonBlock):
|
|
451
|
+
assert isinstance(codeblock, PythonBlock)
|
|
423
452
|
# See global `scan_for_import_issues`
|
|
424
453
|
if not isinstance(codeblock, PythonBlock):
|
|
425
454
|
codeblock = PythonBlock(codeblock)
|
|
@@ -429,6 +458,7 @@ class _MissingImportFinder(object):
|
|
|
429
458
|
# references in doctests to be noted as missing-imports. For now we
|
|
430
459
|
# just let the code accumulate into self.missing_imports and ignore
|
|
431
460
|
# the result.
|
|
461
|
+
logger.debug("unused: %r", self.unused_imports)
|
|
432
462
|
missing_imports = sorted(self.missing_imports)
|
|
433
463
|
if self.parse_docstrings and self.unused_imports is not None:
|
|
434
464
|
doctest_blocks = codeblock.get_doctests()
|
|
@@ -446,10 +476,8 @@ class _MissingImportFinder(object):
|
|
|
446
476
|
# Currently we don't support the 'global' keyword anyway so
|
|
447
477
|
# this doesn't matter yet, and it's uncommon to use 'global'
|
|
448
478
|
# in a doctest, so this is low priority to fix.
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
self._scan_node(block.ast_node)
|
|
452
|
-
self.scopestack = oldstack
|
|
479
|
+
with self._NewScopeCtx(check_unused_imports=False):
|
|
480
|
+
self._scan_node(block.ast_node)
|
|
453
481
|
# Find literal brace identifiers like "... `Foo` ...".
|
|
454
482
|
# TODO: Do this inline: (1) faster; (2) can use proper scope of vars
|
|
455
483
|
# Once we do that, use _check_load() with new args
|
|
@@ -532,17 +560,36 @@ class _MissingImportFinder(object):
|
|
|
532
560
|
|
|
533
561
|
|
|
534
562
|
@contextlib.contextmanager
|
|
535
|
-
def _NewScopeCtx(
|
|
563
|
+
def _NewScopeCtx(
|
|
564
|
+
self,
|
|
565
|
+
include_class_scopes=False,
|
|
566
|
+
new_class_scope=False,
|
|
567
|
+
unhide_classdef=False,
|
|
568
|
+
check_unused_imports=True,
|
|
569
|
+
):
|
|
536
570
|
"""
|
|
537
571
|
Context manager that temporarily pushes a new empty namespace onto the
|
|
538
572
|
stack of namespaces.
|
|
539
573
|
"""
|
|
540
574
|
prev_scopestack = self.scopestack
|
|
541
|
-
new_scopestack = prev_scopestack.
|
|
575
|
+
new_scopestack = prev_scopestack._with_new_scope(
|
|
576
|
+
include_class_scopes=include_class_scopes,
|
|
577
|
+
new_class_scope=new_class_scope,
|
|
578
|
+
unhide_classdef=unhide_classdef,
|
|
579
|
+
)
|
|
542
580
|
self.scopestack = new_scopestack
|
|
543
581
|
try:
|
|
544
582
|
yield
|
|
545
583
|
finally:
|
|
584
|
+
logger.debug("throwing last scope from scopestack: %r", new_scopestack[-1])
|
|
585
|
+
for name, use_checker in new_scopestack[-1].items():
|
|
586
|
+
if use_checker and use_checker.used == False and check_unused_imports:
|
|
587
|
+
logger.debug(
|
|
588
|
+
"unused checker %r scopestack_depth %r",
|
|
589
|
+
use_checker,
|
|
590
|
+
len(self.scopestack),
|
|
591
|
+
)
|
|
592
|
+
self.unused_imports.append((use_checker.lineno, use_checker.source))
|
|
546
593
|
assert self.scopestack is new_scopestack
|
|
547
594
|
self.scopestack = prev_scopestack
|
|
548
595
|
|
|
@@ -588,7 +635,7 @@ class _MissingImportFinder(object):
|
|
|
588
635
|
return
|
|
589
636
|
if (len(node.targets) == 1 and isinstance(node.targets[0], ast.Name)
|
|
590
637
|
and node.targets[0].id == '__all__'):
|
|
591
|
-
if not isinstance(node.value, ast.List):
|
|
638
|
+
if not isinstance(node.value, (ast.List, ast.Tuple)):
|
|
592
639
|
logger.warning("Don't know how to handle __all__ as (%s)" % node.value)
|
|
593
640
|
return
|
|
594
641
|
if not all(_is_ast_str(e) for e in node.value.elts):
|
|
@@ -672,7 +719,7 @@ class _MissingImportFinder(object):
|
|
|
672
719
|
self.visit(node.body)
|
|
673
720
|
self._in_FunctionDef = old_in_FunctionDef
|
|
674
721
|
|
|
675
|
-
def _visit_typecomment(self, typecomment):
|
|
722
|
+
def _visit_typecomment(self, typecomment: str) -> None:
|
|
676
723
|
"""
|
|
677
724
|
Warning, when a type comment the node is a string, not an ast node.
|
|
678
725
|
We also get two types of type comments:
|
|
@@ -695,6 +742,7 @@ class _MissingImportFinder(object):
|
|
|
695
742
|
"""
|
|
696
743
|
if typecomment is None:
|
|
697
744
|
return
|
|
745
|
+
node: Union[ast.Module, ast.FunctionType]
|
|
698
746
|
if '->' in typecomment:
|
|
699
747
|
node = ast.parse(typecomment, mode='func_type')
|
|
700
748
|
else:
|
|
@@ -702,7 +750,7 @@ class _MissingImportFinder(object):
|
|
|
702
750
|
|
|
703
751
|
self.visit(node)
|
|
704
752
|
|
|
705
|
-
def visit_arguments(self, node):
|
|
753
|
+
def visit_arguments(self, node) -> None:
|
|
706
754
|
assert node._fields == ('posonlyargs', 'args', 'vararg', 'kwonlyargs', 'kw_defaults', 'kwarg', 'defaults'), node._fields
|
|
707
755
|
# Argument/parameter list. Note that the defaults should be
|
|
708
756
|
# considered "Load"s from the upper scope, and the argument names are
|
|
@@ -733,7 +781,7 @@ class _MissingImportFinder(object):
|
|
|
733
781
|
else:
|
|
734
782
|
self._visit_Store(node.kwarg)
|
|
735
783
|
|
|
736
|
-
def visit_ExceptHandler(self, node):
|
|
784
|
+
def visit_ExceptHandler(self, node) -> None:
|
|
737
785
|
assert node._fields == ('type', 'name', 'body')
|
|
738
786
|
if node.type:
|
|
739
787
|
self.visit(node.type)
|
|
@@ -909,9 +957,8 @@ class _MissingImportFinder(object):
|
|
|
909
957
|
|
|
910
958
|
def _visit_StoreImport(self, node, modulename):
|
|
911
959
|
name = node.asname or node.name
|
|
912
|
-
logger.debug("_visit_StoreImport(asname=%r,name=%r)",
|
|
913
|
-
|
|
914
|
-
is_star = node.name == '*'
|
|
960
|
+
logger.debug("_visit_StoreImport(asname=%r, name=%r)", node.asname, node.name)
|
|
961
|
+
is_star = node.name == "*"
|
|
915
962
|
if is_star:
|
|
916
963
|
logger.debug("Got star import: line %s: 'from %s import *'",
|
|
917
964
|
self._lineno, modulename)
|
|
@@ -928,7 +975,12 @@ class _MissingImportFinder(object):
|
|
|
928
975
|
value = _UseChecker(name, imp, self._lineno)
|
|
929
976
|
self._visit_Store(name, value)
|
|
930
977
|
|
|
931
|
-
def _visit_Store(self, fullname:str, value=None):
|
|
978
|
+
def _visit_Store(self, fullname: str, value: Optional[_UseChecker] = None):
|
|
979
|
+
"""
|
|
980
|
+
Visit a Store action, check for unused import
|
|
981
|
+
and add current value to the last scope.
|
|
982
|
+
"""
|
|
983
|
+
assert isinstance(value, (_UseChecker, type(None)))
|
|
932
984
|
logger.debug("_visit_Store(%r)", fullname)
|
|
933
985
|
if fullname is None:
|
|
934
986
|
return
|
|
@@ -998,10 +1050,11 @@ class _MissingImportFinder(object):
|
|
|
998
1050
|
# Don't call generic_visit(node) here. Reason: We already visit the
|
|
999
1051
|
# parts above, if relevant.
|
|
1000
1052
|
|
|
1001
|
-
def _visit_Load_defered_global(self, fullname):
|
|
1053
|
+
def _visit_Load_defered_global(self, fullname:str):
|
|
1002
1054
|
"""
|
|
1003
1055
|
Some things will be resolved in global scope later.
|
|
1004
1056
|
"""
|
|
1057
|
+
assert isinstance(fullname, str), fullname
|
|
1005
1058
|
logger.debug("_visit_Load_defered_global(%r)", fullname)
|
|
1006
1059
|
if symbol_needs_import(fullname, self.scopestack):
|
|
1007
1060
|
data = (fullname, self.scopestack, self._lineno)
|
|
@@ -1090,7 +1143,11 @@ class _MissingImportFinder(object):
|
|
|
1090
1143
|
unused_imports.sort()
|
|
1091
1144
|
|
|
1092
1145
|
|
|
1093
|
-
def scan_for_import_issues(
|
|
1146
|
+
def scan_for_import_issues(
|
|
1147
|
+
codeblock: PythonBlock,
|
|
1148
|
+
find_unused_imports: bool = True,
|
|
1149
|
+
parse_docstrings: bool = False,
|
|
1150
|
+
):
|
|
1094
1151
|
"""
|
|
1095
1152
|
Find missing and unused imports, by lineno.
|
|
1096
1153
|
|
|
@@ -1117,7 +1174,7 @@ def scan_for_import_issues(codeblock, find_unused_imports=True, parse_docstrings
|
|
|
1117
1174
|
([], [(1, Import('import baz'))])
|
|
1118
1175
|
|
|
1119
1176
|
"""
|
|
1120
|
-
logger.debug("scan_for_import_issues()")
|
|
1177
|
+
logger.debug("global scan_for_import_issues()")
|
|
1121
1178
|
if not isinstance(codeblock, PythonBlock):
|
|
1122
1179
|
codeblock = PythonBlock(codeblock)
|
|
1123
1180
|
namespaces = ScopeStack([{}])
|
|
@@ -1148,7 +1205,10 @@ def _find_missing_imports_in_ast(node, namespaces):
|
|
|
1148
1205
|
# Traverse the abstract syntax tree.
|
|
1149
1206
|
if logger.debug_enabled:
|
|
1150
1207
|
logger.debug("ast=%s", ast.dump(node))
|
|
1151
|
-
return _MissingImportFinder(
|
|
1208
|
+
return _MissingImportFinder(
|
|
1209
|
+
namespaces,
|
|
1210
|
+
find_unused_imports=False,
|
|
1211
|
+
parse_docstrings=False).find_missing_imports(node)
|
|
1152
1212
|
|
|
1153
1213
|
# TODO: maybe we should replace _find_missing_imports_in_ast with
|
|
1154
1214
|
# _find_missing_imports_in_code(compile(node)). The method of parsing opcodes
|
|
@@ -316,6 +316,14 @@ def _debug_exception(*exc_info, **kwargs):
|
|
|
316
316
|
# will cause print_verbose_tb to include a line with just a colon.
|
|
317
317
|
# TODO: avoid that line.
|
|
318
318
|
exc_info = ("", "", exc_info)
|
|
319
|
+
if exc_info[1]:
|
|
320
|
+
# Explicitly set sys.last_value / sys.last_exc to ensure they are available
|
|
321
|
+
# in the debugger. One use case is that this allows users to call
|
|
322
|
+
# pyflyby.saveframe() within the debugger.
|
|
323
|
+
if sys.version_info < (3, 12):
|
|
324
|
+
sys.last_value = exc_info[1]
|
|
325
|
+
else:
|
|
326
|
+
sys.last_exc = exc_info[1]
|
|
319
327
|
|
|
320
328
|
with _DebuggerCtx(tty=tty) as pdb:
|
|
321
329
|
if debugger_attached:
|
|
@@ -49,6 +49,7 @@ from pyflyby._importclns import ImportSet, Import
|
|
|
49
49
|
|
|
50
50
|
module_dict = {}
|
|
51
51
|
|
|
52
|
+
PYFLYBY_LAZY_LOAD_PREFIX = "from pyflyby_autoimport_"
|
|
52
53
|
|
|
53
54
|
def add_import(names: str, code: str, *, strict: bool = True):
|
|
54
55
|
"""
|
|
@@ -110,8 +111,8 @@ def _add_import(ip, names: str, code: str) -> None:
|
|
|
110
111
|
private version of add_import
|
|
111
112
|
"""
|
|
112
113
|
assert ip is not None
|
|
113
|
-
mang =
|
|
114
|
-
a: FrozenSet[Import] = ImportSet(f"
|
|
114
|
+
mang = PYFLYBY_LAZY_LOAD_PREFIX + names.replace(",", "_").replace(" ", "_")
|
|
115
|
+
a: FrozenSet[Import] = ImportSet(f"{mang} import {names}")._importset
|
|
115
116
|
b: FrozenSet[Import] = ip._auto_importer.db.known_imports._importset
|
|
116
117
|
s_import: FrozenSet[Import] = a | b
|
|
117
118
|
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
# Copyright (C) 2011, 2012, 2013, 2014, 2015 Karl Chen.
|
|
3
3
|
# License: MIT http://opensource.org/licenses/MIT
|
|
4
4
|
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
5
7
|
|
|
6
8
|
|
|
7
9
|
from collections import defaultdict
|
|
@@ -417,7 +419,7 @@ class ImportDB:
|
|
|
417
419
|
return result
|
|
418
420
|
|
|
419
421
|
@classmethod
|
|
420
|
-
def interpret_arg(cls, arg, target_filename):
|
|
422
|
+
def interpret_arg(cls, arg, target_filename) -> ImportDB:
|
|
421
423
|
if arg is None:
|
|
422
424
|
return cls.get_default(target_filename)
|
|
423
425
|
else:
|
|
@@ -560,9 +562,11 @@ class ImportDB:
|
|
|
560
562
|
filenames = [filenames]
|
|
561
563
|
for f in filenames:
|
|
562
564
|
assert isinstance(f, Filename)
|
|
563
|
-
logger.debug(
|
|
564
|
-
|
|
565
|
-
|
|
565
|
+
logger.debug(
|
|
566
|
+
"ImportDB: loading %r, mandatory=%r",
|
|
567
|
+
[str(f) for f in filenames],
|
|
568
|
+
[str(f) for f in _mandatory_filenames_deprecated],
|
|
569
|
+
)
|
|
566
570
|
if SUPPORT_DEPRECATED_BEHAVIOR:
|
|
567
571
|
# Before 2014-10, pyflyby read the following:
|
|
568
572
|
# * known_imports from $PYFLYBY_PATH/known_imports/**/*.py or
|
|
@@ -13,12 +13,12 @@ from pyflyby._parse import PythonBlock
|
|
|
13
13
|
from pyflyby._util import ImportPathCtx, Inf, NullCtx, memoize
|
|
14
14
|
import re
|
|
15
15
|
|
|
16
|
-
from typing import Union
|
|
16
|
+
from typing import Union, Optional, Literal
|
|
17
17
|
|
|
18
18
|
from textwrap import indent
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
class SourceToSourceTransformationBase
|
|
21
|
+
class SourceToSourceTransformationBase:
|
|
22
22
|
|
|
23
23
|
input: PythonBlock
|
|
24
24
|
|
|
@@ -121,7 +121,7 @@ class SourceToSourceFileImportsTransformation(SourceToSourceTransformationBase):
|
|
|
121
121
|
result = [block.pretty_print(params=params) for block in self.blocks]
|
|
122
122
|
return FileText.concatenate(result)
|
|
123
123
|
|
|
124
|
-
def find_import_block_by_lineno(self, lineno):
|
|
124
|
+
def find_import_block_by_lineno(self, lineno: int):
|
|
125
125
|
"""
|
|
126
126
|
Find the import block containing the given line number.
|
|
127
127
|
|
|
@@ -312,11 +312,11 @@ def ImportPathForRelativeImportsCtx(codeblock):
|
|
|
312
312
|
|
|
313
313
|
|
|
314
314
|
def fix_unused_and_missing_imports(
|
|
315
|
-
codeblock: Union[PythonBlock, str],
|
|
316
|
-
add_missing=True,
|
|
317
|
-
remove_unused="AUTOMATIC",
|
|
318
|
-
add_mandatory=True,
|
|
319
|
-
db=None,
|
|
315
|
+
codeblock: Union[PythonBlock, str, Filename],
|
|
316
|
+
add_missing: bool = True,
|
|
317
|
+
remove_unused: Union[Literal["AUTOMATIC"], bool] = "AUTOMATIC",
|
|
318
|
+
add_mandatory: bool = True,
|
|
319
|
+
db: Optional[ImportDB] = None,
|
|
320
320
|
params=None,
|
|
321
321
|
) -> PythonBlock:
|
|
322
322
|
r"""
|
|
@@ -345,6 +345,7 @@ def fix_unused_and_missing_imports(
|
|
|
345
345
|
:rtype:
|
|
346
346
|
`PythonBlock`
|
|
347
347
|
"""
|
|
348
|
+
_codeblock: PythonBlock
|
|
348
349
|
if isinstance(codeblock, Filename):
|
|
349
350
|
_codeblock = PythonBlock(codeblock)
|
|
350
351
|
if not isinstance(codeblock, PythonBlock):
|
|
@@ -393,7 +394,7 @@ def fix_unused_and_missing_imports(
|
|
|
393
394
|
logger.error(
|
|
394
395
|
"%s: couldn't remove import %r", filename, imp,)
|
|
395
396
|
except LineNumberNotFoundError as e:
|
|
396
|
-
logger.
|
|
397
|
+
logger.debug(
|
|
397
398
|
"%s: unused import %r on line %d not global",
|
|
398
399
|
filename, str(imp), e.args[0])
|
|
399
400
|
else:
|