sphinx-codeautolink 0.17.5__tar.gz → 0.18.0__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.
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/PKG-INFO +2 -1
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/docs/src/about.rst +22 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/docs/src/release_notes.rst +9 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/pyproject.toml +1 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/__init__.py +1 -1
- sphinx_codeautolink-0.18.0/src/sphinx_codeautolink/extension/resolve.py +307 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/parse.py +14 -3
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink.egg-info/PKG-INFO +2 -1
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink.egg-info/SOURCES.txt +7 -0
- sphinx_codeautolink-0.18.0/tests/extension/ref/ref_for_loop.txt +26 -0
- sphinx_codeautolink-0.18.0/tests/extension/ref/ref_module_attribute.txt +13 -0
- sphinx_codeautolink-0.18.0/tests/extension/ref/ref_module_attribute_builtin.txt +13 -0
- sphinx_codeautolink-0.18.0/tests/extension/ref/ref_module_attribute_class.txt +13 -0
- sphinx_codeautolink-0.18.0/tests/extension/ref/ref_type_checking_gated.txt +15 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/src/test_project/__init__.py +23 -0
- sphinx_codeautolink-0.18.0/tests/extension/src/type_checking/__init__.py +19 -0
- sphinx_codeautolink-0.18.0/tests/extension/src/type_checking/foo.py +4 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/parse/assign.py +25 -1
- sphinx_codeautolink-0.17.5/src/sphinx_codeautolink/extension/resolve.py +0 -178
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/LICENSE +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/MANIFEST.in +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/contributing.rst +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/docs/requirements.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/docs/src/404.rst +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/docs/src/conf.py +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/docs/src/example_library.rst +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/docs/src/examples.rst +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/docs/src/index.rst +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/docs/src/lib.py +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/docs/src/reference.rst +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/docs/src/static/custom.css +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/readme_pypi.rst +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/requirements/build +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/requirements/dev +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/requirements/docs +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/requirements/extras +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/requirements/tests +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/setup.cfg +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/extension/__init__.py +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/extension/backref.py +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/extension/block.py +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/extension/cache.py +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/extension/directive.py +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/extension/translation.py +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/de/LC_MESSAGES/sphinx-codeautolink.mo +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/de/LC_MESSAGES/sphinx-codeautolink.po +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/es/LC_MESSAGES/sphinx-codeautolink.mo +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/es/LC_MESSAGES/sphinx-codeautolink.po +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/fi/LC_MESSAGES/sphinx-codeautolink.mo +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/fi/LC_MESSAGES/sphinx-codeautolink.po +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/fr/LC_MESSAGES/sphinx-codeautolink.mo +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/fr/LC_MESSAGES/sphinx-codeautolink.po +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/it/LC_MESSAGES/sphinx-codeautolink.mo +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/it/LC_MESSAGES/sphinx-codeautolink.po +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/nl/LC_MESSAGES/sphinx-codeautolink.mo +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/nl/LC_MESSAGES/sphinx-codeautolink.po +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/ru/LC_MESSAGES/sphinx-codeautolink.po +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/sphinx-codeautolink.pot +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/uk/LC_MESSAGES/sphinx-codeautolink.po +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/static/sphinx-codeautolink.css +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/warn.py +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink.egg-info/dependency_links.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink.egg-info/requires.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink.egg-info/top_level.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/__init__.py +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/__init__.py +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/_check.py +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/fail/concat_invalid.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/fail/custom_block_import_invalid.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/fail/custom_block_syntax_error.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/fail/failed_resolve_invalid_location.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/fail/failed_resolve_no_module.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/fail/failed_resolve_return_type.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/fail/match_block_warning.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/fail/missing_inventory.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/fail/no_backreference.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/fail/no_module_docs.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/fail/preface_invalid_arg.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/fail/ref_import_star_invalid.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/fail/ref_invalid_block_type.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/fail/ref_invalid_syntax.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/fail/ref_invalid_syntax_complex.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/fail/ref_ipython_non-python.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/fail/skip_invalid.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/class_mro_fix.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/concat_default.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/concat_off.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/concat_on_across_sections.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/concat_on_breaks.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/concat_section_breaks.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/concat_section_returns_to_global.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/custom_block.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/custom_block_imported.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/empty_project.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/inventory_map_is_needed.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/inventory_map_not_needed.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_Python.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_bazel.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_default.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_default_fail.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_doctest.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_doctest_empty_input.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_extdoctest_doctest.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_extdoctest_setup.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_extdoctest_setup_wrong.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_extdoctest_testcode.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_highlight_language.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_highlight_none.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_ipython.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_ipython3.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_ipython_directive.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_ipython_directive_comment.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_ipython_syntax.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_literal.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_non_python_block.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_py.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_py3.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_pycon.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_pycon_implicit.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_pyi.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_python3.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_sage.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_starlark.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/line_numbers.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/preface_concatenated.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/preface_consumed_non_python.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/preface_document.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/preface_global.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/preface_global_multiline.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/preface_global_overwritten.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/preface_multiline.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/preface_multiline_and_arg.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/preface_multiple.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/preface_single.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_assign_targets.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_builtins.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_chain.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_chain_call.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_class_attr.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_class_meth_returns_self.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_class_type_attr.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_decorator.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_fluent_attrs.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_fluent_call.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_func_args.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_func_no_module.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_import_as.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_import_from.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_import_from_complex.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_import_multiple.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_import_multiple_libs.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_import_star.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_import_submodule.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_imported_func.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_imported_func_relocated.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_inherited.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_intersphinx_only.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_invalid_func.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_invalid_typehint.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_optional.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_optional_future.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_shadow_builtin.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_simple.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/search_css_duplicates_removed.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/skip_file.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/skip_next.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/skip_next_consumed_non_python.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/skip_off.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/ref/skip_section.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/src/class_mro_fix.py +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/src/future_project.py +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/src/parser_func.py +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/src/test_project/sub.py +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/table/tab_autodoc_empty.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/table/tab_autodoc_links.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/table/tab_manual_collapse.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/table/tab_manual_empty.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/table/tab_manual_links.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/table/tab_manual_links_subsection.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/extension/table/tab_no_table.txt +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/parse/__init__.py +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/parse/_util.py +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/parse/chain.py +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/parse/match.py +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tests/parse/scope.py +0 -0
- {sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/tox.ini +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sphinx-codeautolink
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.18.0
|
|
4
4
|
Summary: Automatic links from code examples to reference documentation.
|
|
5
5
|
Author-email: Felix Hildén <felix.hilden@gmail.com>
|
|
6
6
|
Maintainer-email: Felix Hildén <felix.hilden@gmail.com>
|
|
@@ -19,6 +19,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
22
23
|
Classifier: Topic :: Documentation
|
|
23
24
|
Classifier: Topic :: Documentation :: Sphinx
|
|
24
25
|
Classifier: Topic :: Software Development :: Documentation
|
|
@@ -85,6 +85,28 @@ The extension parses code blocks in the ``doctree-read`` Sphinx event.
|
|
|
85
85
|
The priority is set to 490 to catch nodes removed by ``sphinx.ext.doctest``
|
|
86
86
|
(priority 500). In other cases the priority of the extension is default.
|
|
87
87
|
|
|
88
|
+
Type checking blocks
|
|
89
|
+
********************
|
|
90
|
+
To resolve annotations that reference names imported under
|
|
91
|
+
``if TYPE_CHECKING:``, the extension re-executes the bodies of those gated
|
|
92
|
+
blocks in the importing module's own namespace the first time it inspects
|
|
93
|
+
that module. Without this step, ``typing.get_type_hints`` would fail with
|
|
94
|
+
``NameError`` because, at runtime, ``TYPE_CHECKING`` is ``False`` and the
|
|
95
|
+
gated names are never bound.
|
|
96
|
+
|
|
97
|
+
A few things to be aware of:
|
|
98
|
+
|
|
99
|
+
- Only top-level ``if`` blocks whose condition is ``TYPE_CHECKING`` or
|
|
100
|
+
``MYPY`` (as a bare name or attribute access, e.g. ``typing.TYPE_CHECKING``)
|
|
101
|
+
are recognised. The condition is matched by AST shape, not evaluated.
|
|
102
|
+
- The original module objects are mutated in place:
|
|
103
|
+
names that would normally only exist for type checkers become real
|
|
104
|
+
attributes on the module.
|
|
105
|
+
- Bodies are executed with the equivalent of ``exec`` in the module's
|
|
106
|
+
globals. If execution fails, for example due to a cyclic import or
|
|
107
|
+
a missing optional dependency, that block is silently skipped and the rest
|
|
108
|
+
of the module continues to work.
|
|
109
|
+
|
|
88
110
|
Copying code blocks
|
|
89
111
|
-------------------
|
|
90
112
|
If you feel like code links make copying code a bit more difficult,
|
|
@@ -8,6 +8,15 @@ These release notes are based on
|
|
|
8
8
|
sphinx-codeautolink adheres to
|
|
9
9
|
`Semantic Versioning <https://semver.org>`_.
|
|
10
10
|
|
|
11
|
+
0.18.0 (2026-04-25)
|
|
12
|
+
-------------------
|
|
13
|
+
- Support module attributes and class aliases (:issue:`65`)
|
|
14
|
+
- Resolve for-loop iterables into targets. ``for target in lib.iterable():``
|
|
15
|
+
now links ``target.method()`` in the loop body (:issue:`196`)
|
|
16
|
+
- Resolve return annotations that reference names imported inside
|
|
17
|
+
``if TYPE_CHECKING:`` and similar blocks (:issue:`197`)
|
|
18
|
+
- Support Python 3.14 officially (:issue:`198`)
|
|
19
|
+
|
|
11
20
|
0.17.5 (2025-07-09)
|
|
12
21
|
-------------------
|
|
13
22
|
- Add ``Python`` to default lexers (:issue:`194`)
|
|
@@ -30,6 +30,7 @@ classifiers = [
|
|
|
30
30
|
"Programming Language :: Python :: 3.11",
|
|
31
31
|
"Programming Language :: Python :: 3.12",
|
|
32
32
|
"Programming Language :: Python :: 3.13",
|
|
33
|
+
"Programming Language :: Python :: 3.14",
|
|
33
34
|
"Topic :: Documentation",
|
|
34
35
|
"Topic :: Documentation :: Sphinx",
|
|
35
36
|
"Topic :: Software Development :: Documentation",
|
{sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/__init__.py
RENAMED
|
@@ -8,7 +8,7 @@ from .extension import SphinxCodeAutoLink, backref, directive
|
|
|
8
8
|
from .extension.block import clean_ipython, clean_pycon
|
|
9
9
|
from .extension.translation import MESSAGE_CATALOG_NAME
|
|
10
10
|
|
|
11
|
-
__version__ = "0.
|
|
11
|
+
__version__ = "0.18.0"
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
def setup(app: Sphinx):
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
"""Resolve import locations and type hints."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import ast
|
|
6
|
+
import inspect
|
|
7
|
+
from collections import abc
|
|
8
|
+
from collections.abc import Callable
|
|
9
|
+
from contextlib import suppress
|
|
10
|
+
from dataclasses import dataclass
|
|
11
|
+
from functools import cache
|
|
12
|
+
from importlib import import_module
|
|
13
|
+
from inspect import isclass, ismodule, isroutine
|
|
14
|
+
from types import ModuleType, UnionType
|
|
15
|
+
from typing import Any, Union, get_type_hints
|
|
16
|
+
|
|
17
|
+
from sphinx_codeautolink.parse import Name, NameBreak
|
|
18
|
+
|
|
19
|
+
# Containers whose first generic argument is the element type produced
|
|
20
|
+
# by iteration. ``tuple`` only fits ``tuple[T, ...]``; for mixed tuples
|
|
21
|
+
# like ``tuple[int, str]`` we pick the first arg, which may be wrong.
|
|
22
|
+
ITERABLE_ORIGINS = frozenset(
|
|
23
|
+
{
|
|
24
|
+
abc.Iterable,
|
|
25
|
+
abc.Iterator,
|
|
26
|
+
abc.Generator,
|
|
27
|
+
abc.AsyncIterable,
|
|
28
|
+
abc.AsyncIterator,
|
|
29
|
+
abc.AsyncGenerator,
|
|
30
|
+
abc.Collection,
|
|
31
|
+
abc.Sequence,
|
|
32
|
+
abc.MutableSequence,
|
|
33
|
+
abc.Set,
|
|
34
|
+
abc.MutableSet,
|
|
35
|
+
abc.Mapping,
|
|
36
|
+
abc.MutableMapping,
|
|
37
|
+
list,
|
|
38
|
+
set,
|
|
39
|
+
frozenset,
|
|
40
|
+
tuple,
|
|
41
|
+
dict,
|
|
42
|
+
}
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def resolve_location(chain: Name, inventory) -> str:
|
|
47
|
+
"""Find the final type that a name refers to."""
|
|
48
|
+
segments: list[tuple[list[str], NameBreak | None]] = []
|
|
49
|
+
current: list[str] = []
|
|
50
|
+
for comp in chain.import_components:
|
|
51
|
+
if comp in (NameBreak.call, NameBreak.for_iter):
|
|
52
|
+
segments.append((current, NameBreak(comp)))
|
|
53
|
+
current = []
|
|
54
|
+
else:
|
|
55
|
+
current.append(comp)
|
|
56
|
+
segments.append((current, None))
|
|
57
|
+
|
|
58
|
+
cursor = None
|
|
59
|
+
last = len(segments) - 1
|
|
60
|
+
for i, (segment, terminator) in enumerate(segments):
|
|
61
|
+
comps = segment
|
|
62
|
+
if cursor is None:
|
|
63
|
+
try:
|
|
64
|
+
comps, cursor = make_cursor(comps)
|
|
65
|
+
except CouldNotResolve:
|
|
66
|
+
if i == last:
|
|
67
|
+
# Last ditch effort to locate based on the string only
|
|
68
|
+
return ".".join(comps)
|
|
69
|
+
raise
|
|
70
|
+
cursor = locate_type(cursor, tuple(comps), inventory)
|
|
71
|
+
if terminator == NameBreak.call:
|
|
72
|
+
call_value(cursor)
|
|
73
|
+
elif terminator == NameBreak.for_iter:
|
|
74
|
+
iter_value(cursor)
|
|
75
|
+
return cursor.location if cursor is not None else None
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class CouldNotResolve(Exception): # noqa: N818
|
|
79
|
+
"""Could not resolve type to inventory."""
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@dataclass
|
|
83
|
+
class Cursor:
|
|
84
|
+
"""Cursor to follow a component path to the final type."""
|
|
85
|
+
|
|
86
|
+
location: str
|
|
87
|
+
value: Any
|
|
88
|
+
instance: bool
|
|
89
|
+
annotation: Any = None
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def make_cursor(components: list[str]) -> tuple[list[str], Cursor]:
|
|
93
|
+
"""Divide components into module and rest, create cursor for following the rest."""
|
|
94
|
+
value, index = closest_module(tuple(components))
|
|
95
|
+
location = ".".join(components[:index])
|
|
96
|
+
return components[index:], Cursor(location, value, instance=False)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def locate_type(cursor: Cursor, components: tuple[str, ...], inventory) -> Cursor:
|
|
100
|
+
"""Find type hint and resolve to new location."""
|
|
101
|
+
previous = cursor
|
|
102
|
+
for i, component in enumerate(components):
|
|
103
|
+
previous = cursor
|
|
104
|
+
|
|
105
|
+
# When descending through an instance or alias
|
|
106
|
+
# try to normalise to the original type if possible
|
|
107
|
+
if previous.value is not None and not (
|
|
108
|
+
isclass(previous.value)
|
|
109
|
+
or ismodule(previous.value)
|
|
110
|
+
or isroutine(previous.value)
|
|
111
|
+
):
|
|
112
|
+
with suppress(AttributeError, TypeError):
|
|
113
|
+
previous.value = type(previous.value)
|
|
114
|
+
previous.location = fully_qualified_name(previous.value)
|
|
115
|
+
|
|
116
|
+
annotation = None
|
|
117
|
+
with suppress(NameError, TypeError):
|
|
118
|
+
annotation = get_type_hints(previous.value).get(component)
|
|
119
|
+
cursor = Cursor(
|
|
120
|
+
previous.location + "." + component,
|
|
121
|
+
getattr(previous.value, component, None),
|
|
122
|
+
previous.instance,
|
|
123
|
+
annotation=annotation,
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
if cursor.value is None:
|
|
127
|
+
msg = f"{cursor.location} does not exist."
|
|
128
|
+
raise CouldNotResolve(msg)
|
|
129
|
+
|
|
130
|
+
if isclass(cursor.value):
|
|
131
|
+
cursor.instance = False
|
|
132
|
+
|
|
133
|
+
if isclass(cursor.value) or (
|
|
134
|
+
isroutine(cursor.value) and cursor.location not in inventory
|
|
135
|
+
):
|
|
136
|
+
# Normalise location of type or imported function
|
|
137
|
+
# If odd construct encountered: don't try to be clever but continue
|
|
138
|
+
with suppress(AttributeError, TypeError):
|
|
139
|
+
cursor.location = fully_qualified_name(cursor.value)
|
|
140
|
+
|
|
141
|
+
# Check bases if member not found in current class
|
|
142
|
+
if isclass(previous.value) and cursor.location not in inventory:
|
|
143
|
+
for val in previous.value.__mro__[1:]:
|
|
144
|
+
name = fully_qualified_name(val)
|
|
145
|
+
if name + "." + component in inventory:
|
|
146
|
+
previous.location = name
|
|
147
|
+
return locate_type(previous, components[i:], inventory)
|
|
148
|
+
|
|
149
|
+
return cursor
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def call_value(cursor: Cursor) -> None:
|
|
153
|
+
"""Call class, instance or function."""
|
|
154
|
+
if isclass(cursor.value) and not cursor.instance:
|
|
155
|
+
# class definition: "instantiate" class
|
|
156
|
+
cursor.instance = True
|
|
157
|
+
return
|
|
158
|
+
|
|
159
|
+
if callable(cursor.value) and not isroutine(cursor.value):
|
|
160
|
+
# callable class instance
|
|
161
|
+
cursor.value = cursor.value.__call__
|
|
162
|
+
elif not isroutine(cursor.value):
|
|
163
|
+
raise CouldNotResolve # not a function either
|
|
164
|
+
|
|
165
|
+
annotation = get_return_annotation(cursor.value)
|
|
166
|
+
type_ = origin_type(annotation)
|
|
167
|
+
if not isinstance(type_, type):
|
|
168
|
+
msg = f"Unable to follow return annotation of {annotation!r}."
|
|
169
|
+
raise CouldNotResolve(msg)
|
|
170
|
+
cursor.value = type_
|
|
171
|
+
cursor.location = fully_qualified_name(type_)
|
|
172
|
+
cursor.instance = True
|
|
173
|
+
cursor.annotation = annotation
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def iter_value(cursor: Cursor) -> None:
|
|
177
|
+
"""Unwrap the iterable cursor points to into its element type."""
|
|
178
|
+
element = unwrap_iterable(strip_optional(cursor.annotation))
|
|
179
|
+
if not isinstance(element, type):
|
|
180
|
+
msg = (
|
|
181
|
+
f"Unable to unwrap iterable element type of"
|
|
182
|
+
f" {get_name_for_debugging(cursor.value)}."
|
|
183
|
+
)
|
|
184
|
+
raise CouldNotResolve(msg)
|
|
185
|
+
cursor.value = element
|
|
186
|
+
cursor.location = fully_qualified_name(element)
|
|
187
|
+
cursor.instance = True
|
|
188
|
+
cursor.annotation = None
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def strip_optional(annotation: Any) -> Any:
|
|
192
|
+
"""Reduce ``Optional[T]`` / ``T | None`` to ``T``; otherwise return as-is."""
|
|
193
|
+
origin = getattr(annotation, "__origin__", None)
|
|
194
|
+
args = getattr(annotation, "__args__", None)
|
|
195
|
+
if (origin is Union or isinstance(annotation, UnionType)) and args:
|
|
196
|
+
non_none = [a for a in args if a is not type(None)]
|
|
197
|
+
if len(non_none) == 1:
|
|
198
|
+
return non_none[0]
|
|
199
|
+
return annotation
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def origin_type(annotation: Any) -> Any:
|
|
203
|
+
"""Return underlying type of an annotation (e.g. ``list`` from ``list[Foo]``)."""
|
|
204
|
+
return getattr(annotation, "__origin__", None) or annotation
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def unwrap_iterable(annotation: Any) -> type | None:
|
|
208
|
+
"""Return the element type of an iterable annotation, or None."""
|
|
209
|
+
origin = getattr(annotation, "__origin__", None)
|
|
210
|
+
args = getattr(annotation, "__args__", None)
|
|
211
|
+
if origin in ITERABLE_ORIGINS and args:
|
|
212
|
+
return args[0]
|
|
213
|
+
return None
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def get_return_annotation(func: Callable) -> Any:
|
|
217
|
+
"""Determine the target of a function return type hint."""
|
|
218
|
+
try:
|
|
219
|
+
annotation = get_type_hints(func).get("return")
|
|
220
|
+
except (NameError, TypeError) as e:
|
|
221
|
+
msg = f"Unable to follow return annotation of {get_name_for_debugging(func)}."
|
|
222
|
+
raise CouldNotResolve(msg) from e
|
|
223
|
+
if not annotation:
|
|
224
|
+
msg = f"No return annotation on {get_name_for_debugging(func)}."
|
|
225
|
+
raise CouldNotResolve(msg)
|
|
226
|
+
return strip_optional(annotation)
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def fully_qualified_name(thing: type | Callable) -> str:
|
|
230
|
+
"""Construct the fully qualified name of a type."""
|
|
231
|
+
return thing.__module__ + "." + thing.__qualname__
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def get_name_for_debugging(thing: type | Callable) -> str:
|
|
235
|
+
"""Construct the fully qualified name or some readable information of a type."""
|
|
236
|
+
try:
|
|
237
|
+
return fully_qualified_name(thing)
|
|
238
|
+
except (AttributeError, TypeError):
|
|
239
|
+
return repr(thing)
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
@cache
|
|
243
|
+
def closest_module(components: tuple[str, ...]) -> tuple[Any, int]:
|
|
244
|
+
"""Find closest importable module."""
|
|
245
|
+
try:
|
|
246
|
+
mod = import_module(components[0])
|
|
247
|
+
except ImportError as e:
|
|
248
|
+
msg = f"Could not import {components[0]}."
|
|
249
|
+
raise CouldNotResolve(msg) from e
|
|
250
|
+
populate_type_checking(mod)
|
|
251
|
+
|
|
252
|
+
for i in range(1, len(components)):
|
|
253
|
+
try:
|
|
254
|
+
mod = import_module(".".join(components[: i + 1]))
|
|
255
|
+
except ImportError:
|
|
256
|
+
# import failed, exclude previously added item
|
|
257
|
+
return mod, i
|
|
258
|
+
populate_type_checking(mod)
|
|
259
|
+
# imports succeeded, include all items
|
|
260
|
+
return mod, len(components)
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
populated_modules: set[int] = set()
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
def populate_type_checking(mod: ModuleType) -> None:
|
|
267
|
+
"""
|
|
268
|
+
Execute top-level TYPE_CHECKING blocks into ``mod.__dict__``.
|
|
269
|
+
|
|
270
|
+
At runtime TYPE_CHECKING is False, so names imported under such gates
|
|
271
|
+
are never bound on the module. ``get_type_hints`` then fails to resolve
|
|
272
|
+
annotations that reference them. Re-execute the gated bodies in the
|
|
273
|
+
module's own namespace so those names become available.
|
|
274
|
+
"""
|
|
275
|
+
if id(mod) in populated_modules:
|
|
276
|
+
return
|
|
277
|
+
populated_modules.add(id(mod))
|
|
278
|
+
|
|
279
|
+
try:
|
|
280
|
+
source = inspect.getsource(mod)
|
|
281
|
+
except (OSError, TypeError):
|
|
282
|
+
return
|
|
283
|
+
|
|
284
|
+
tree = ast.parse(source)
|
|
285
|
+
|
|
286
|
+
filename = getattr(mod, "__file__", None) or "<type_checking>"
|
|
287
|
+
for node in tree.body:
|
|
288
|
+
if not isinstance(node, ast.If) or not is_type_checking_test(node.test):
|
|
289
|
+
continue
|
|
290
|
+
body = ast.Module(body=node.body, type_ignores=[])
|
|
291
|
+
# Catch e.g. optional deps and cyclic imports
|
|
292
|
+
with suppress(Exception):
|
|
293
|
+
exec(compile(body, filename, "exec"), mod.__dict__) # noqa: S102
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
def is_type_checking_test(expr: ast.expr) -> bool:
|
|
297
|
+
"""
|
|
298
|
+
Determine if expr is a test for type checking.
|
|
299
|
+
|
|
300
|
+
Mirror mypy's ``infer_condition_value``: match a bare name or any
|
|
301
|
+
attribute access regardless of qualifier.
|
|
302
|
+
"""
|
|
303
|
+
if isinstance(expr, ast.Name):
|
|
304
|
+
return expr.id in ("TYPE_CHECKING", "MYPY")
|
|
305
|
+
if isinstance(expr, ast.Attribute):
|
|
306
|
+
return expr.attr in ("TYPE_CHECKING", "MYPY")
|
|
307
|
+
return False
|
|
@@ -94,6 +94,7 @@ class NameBreak(str, Enum):
|
|
|
94
94
|
call = "()"
|
|
95
95
|
namedexpr = ":="
|
|
96
96
|
import_from = ">"
|
|
97
|
+
for_iter = "<>"
|
|
97
98
|
|
|
98
99
|
|
|
99
100
|
class LinkContext(str, Enum):
|
|
@@ -499,9 +500,19 @@ class ImportTrackerVisitor(ast.NodeVisitor):
|
|
|
499
500
|
self.visit_For(node)
|
|
500
501
|
|
|
501
502
|
def visit_For(self, node: ast.For | ast.AsyncFor) -> None:
|
|
502
|
-
"""Swap node order."""
|
|
503
|
-
self.visit(node.iter)
|
|
504
|
-
|
|
503
|
+
"""Swap node order and resolve iterators."""
|
|
504
|
+
iter_pending = self.visit(node.iter)
|
|
505
|
+
|
|
506
|
+
if (
|
|
507
|
+
isinstance(iter_pending, PendingAccess)
|
|
508
|
+
and iter_pending.components
|
|
509
|
+
and isinstance(node.target, ast.Name)
|
|
510
|
+
):
|
|
511
|
+
marker = Component(NameBreak.for_iter.value, *linenos(node), "load")
|
|
512
|
+
self.assign_name(node.target.id, [*iter_pending.components, marker])
|
|
513
|
+
else:
|
|
514
|
+
self.visit(node.target)
|
|
515
|
+
|
|
505
516
|
for n in node.body:
|
|
506
517
|
self.visit(n)
|
|
507
518
|
for n in node.orelse:
|
{sphinx_codeautolink-0.17.5 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink.egg-info/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sphinx-codeautolink
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.18.0
|
|
4
4
|
Summary: Automatic links from code examples to reference documentation.
|
|
5
5
|
Author-email: Felix Hildén <felix.hilden@gmail.com>
|
|
6
6
|
Maintainer-email: Felix Hildén <felix.hilden@gmail.com>
|
|
@@ -19,6 +19,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
22
23
|
Classifier: Topic :: Documentation
|
|
23
24
|
Classifier: Topic :: Documentation :: Sphinx
|
|
24
25
|
Classifier: Topic :: Software Development :: Documentation
|
|
@@ -131,6 +131,7 @@ tests/extension/ref/ref_class_type_attr.txt
|
|
|
131
131
|
tests/extension/ref/ref_decorator.txt
|
|
132
132
|
tests/extension/ref/ref_fluent_attrs.txt
|
|
133
133
|
tests/extension/ref/ref_fluent_call.txt
|
|
134
|
+
tests/extension/ref/ref_for_loop.txt
|
|
134
135
|
tests/extension/ref/ref_func_args.txt
|
|
135
136
|
tests/extension/ref/ref_func_no_module.txt
|
|
136
137
|
tests/extension/ref/ref_import_as.txt
|
|
@@ -146,10 +147,14 @@ tests/extension/ref/ref_inherited.txt
|
|
|
146
147
|
tests/extension/ref/ref_intersphinx_only.txt
|
|
147
148
|
tests/extension/ref/ref_invalid_func.txt
|
|
148
149
|
tests/extension/ref/ref_invalid_typehint.txt
|
|
150
|
+
tests/extension/ref/ref_module_attribute.txt
|
|
151
|
+
tests/extension/ref/ref_module_attribute_builtin.txt
|
|
152
|
+
tests/extension/ref/ref_module_attribute_class.txt
|
|
149
153
|
tests/extension/ref/ref_optional.txt
|
|
150
154
|
tests/extension/ref/ref_optional_future.txt
|
|
151
155
|
tests/extension/ref/ref_shadow_builtin.txt
|
|
152
156
|
tests/extension/ref/ref_simple.txt
|
|
157
|
+
tests/extension/ref/ref_type_checking_gated.txt
|
|
153
158
|
tests/extension/ref/search_css_duplicates_removed.txt
|
|
154
159
|
tests/extension/ref/skip_file.txt
|
|
155
160
|
tests/extension/ref/skip_next.txt
|
|
@@ -161,6 +166,8 @@ tests/extension/src/future_project.py
|
|
|
161
166
|
tests/extension/src/parser_func.py
|
|
162
167
|
tests/extension/src/test_project/__init__.py
|
|
163
168
|
tests/extension/src/test_project/sub.py
|
|
169
|
+
tests/extension/src/type_checking/__init__.py
|
|
170
|
+
tests/extension/src/type_checking/foo.py
|
|
164
171
|
tests/extension/table/tab_autodoc_empty.txt
|
|
165
172
|
tests/extension/table/tab_autodoc_links.txt
|
|
166
173
|
tests/extension/table/tab_manual_collapse.txt
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
test_project
|
|
2
|
+
test_project.mod_list
|
|
3
|
+
a.meth
|
|
4
|
+
test_project.mod_typing_list
|
|
5
|
+
b.meth
|
|
6
|
+
test_project.iter_foos
|
|
7
|
+
c.meth
|
|
8
|
+
# split
|
|
9
|
+
# split
|
|
10
|
+
Test project
|
|
11
|
+
============
|
|
12
|
+
|
|
13
|
+
.. code:: python
|
|
14
|
+
|
|
15
|
+
import test_project
|
|
16
|
+
|
|
17
|
+
for a in test_project.mod_list:
|
|
18
|
+
a.meth()
|
|
19
|
+
|
|
20
|
+
for b in test_project.mod_typing_list:
|
|
21
|
+
b.meth()
|
|
22
|
+
|
|
23
|
+
for c in test_project.iter_foos():
|
|
24
|
+
c.meth()
|
|
25
|
+
|
|
26
|
+
.. automodule:: test_project
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
"""Docstring."""
|
|
2
2
|
|
|
3
|
+
from collections.abc import Iterator
|
|
4
|
+
from typing import List # noqa: UP035
|
|
5
|
+
|
|
3
6
|
from .sub import SubBar, subfoo # noqa: F401
|
|
4
7
|
|
|
5
8
|
|
|
@@ -25,10 +28,30 @@ class Foo:
|
|
|
25
28
|
"""Test call."""
|
|
26
29
|
|
|
27
30
|
|
|
31
|
+
mod_attr: Foo = Foo()
|
|
32
|
+
"""Module attribute."""
|
|
33
|
+
|
|
34
|
+
mod_int: int = 0
|
|
35
|
+
"""Module attribute with a builtin type."""
|
|
36
|
+
|
|
37
|
+
mod_type = Foo
|
|
38
|
+
"""Module attribute whose value is a class, not an instance."""
|
|
39
|
+
|
|
40
|
+
mod_list: list[Foo] = []
|
|
41
|
+
"""Module list attribute."""
|
|
42
|
+
|
|
43
|
+
mod_typing_list: List[Foo] = [] # noqa: UP006
|
|
44
|
+
"""Typing module list attribute."""
|
|
45
|
+
|
|
46
|
+
|
|
28
47
|
def bar() -> Foo:
|
|
29
48
|
"""Bar test function."""
|
|
30
49
|
|
|
31
50
|
|
|
51
|
+
def iter_foos() -> "Iterator[Foo]":
|
|
52
|
+
"""Return an iterator of Foos."""
|
|
53
|
+
|
|
54
|
+
|
|
32
55
|
def optional() -> Foo | None:
|
|
33
56
|
"""Return optional type."""
|
|
34
57
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import typing
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
from collections.abc import Collection
|
|
8
|
+
|
|
9
|
+
if typing.TYPE_CHECKING:
|
|
10
|
+
from .foo import Foo
|
|
11
|
+
|
|
12
|
+
if False:
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def pick(items: Collection[str]) -> Foo:
|
|
17
|
+
"""Return value whose annotation references a name guarded by
|
|
18
|
+
``if TYPE_CHECKING: ...``
|
|
19
|
+
"""
|
|
@@ -298,7 +298,7 @@ class TestAssignLike:
|
|
|
298
298
|
return s, refs
|
|
299
299
|
|
|
300
300
|
@refs_equal
|
|
301
|
-
def
|
|
301
|
+
def test_for_uses_imported_but_target_unused(self):
|
|
302
302
|
s = "import a\nfor b in a:\n a"
|
|
303
303
|
refs = [("a", "a"), ("a", "a"), ("a", "a")]
|
|
304
304
|
return s, refs
|
|
@@ -312,6 +312,30 @@ class TestAssignLike:
|
|
|
312
312
|
@refs_equal
|
|
313
313
|
def test_for_uses_and_overwrites_imported(self):
|
|
314
314
|
s = "import a\nfor a in a:\n a"
|
|
315
|
+
refs = [("a", "a"), ("a", "a"), ("a.<>", "a")]
|
|
316
|
+
return s, refs
|
|
317
|
+
|
|
318
|
+
@refs_equal
|
|
319
|
+
def test_for_target_bound_to_iter_name_element(self):
|
|
320
|
+
s = "import a\nfor b in a:\n b"
|
|
321
|
+
refs = [("a", "a"), ("a", "a"), ("a.<>", "b")]
|
|
322
|
+
return s, refs
|
|
323
|
+
|
|
324
|
+
@refs_equal
|
|
325
|
+
def test_for_target_bound_to_iter_call_element(self):
|
|
326
|
+
s = "import a\nfor b in a():\n b"
|
|
327
|
+
refs = [("a", "a"), ("a", "a"), ("a.().<>", "b")]
|
|
328
|
+
return s, refs
|
|
329
|
+
|
|
330
|
+
@refs_equal
|
|
331
|
+
def test_for_target_bound_to_iter_attribute_element(self):
|
|
332
|
+
s = "import a\nfor b in a.x:\n b"
|
|
333
|
+
refs = [("a", "a"), ("a.x", "a.x"), ("a.x.<>", "b")]
|
|
334
|
+
return s, refs
|
|
335
|
+
|
|
336
|
+
@refs_equal
|
|
337
|
+
def test_for_tuple_target_not_bound(self):
|
|
338
|
+
s = "import a\nfor b, c in a():\n b"
|
|
315
339
|
refs = [("a", "a"), ("a", "a")]
|
|
316
340
|
return s, refs
|
|
317
341
|
|