sphinx-codeautolink 0.17.4__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.4 → sphinx_codeautolink-0.18.0}/PKG-INFO +4 -24
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/docs/src/about.rst +22 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/docs/src/release_notes.rst +13 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/pyproject.toml +3 -2
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/__init__.py +1 -1
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/extension/__init__.py +1 -1
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/extension/block.py +2 -1
- sphinx_codeautolink-0.18.0/src/sphinx_codeautolink/extension/resolve.py +307 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/parse.py +14 -3
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink.egg-info/PKG-INFO +4 -24
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink.egg-info/SOURCES.txt +8 -0
- sphinx_codeautolink-0.18.0/tests/extension/ref/lexer_Python.txt +13 -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.4 → sphinx_codeautolink-0.18.0}/tests/extension/src/future_project.py +1 -1
- {sphinx_codeautolink-0.17.4 → 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.4 → sphinx_codeautolink-0.18.0}/tests/parse/assign.py +25 -1
- sphinx_codeautolink-0.17.4/src/sphinx_codeautolink/extension/resolve.py +0 -178
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/LICENSE +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/MANIFEST.in +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/contributing.rst +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/docs/requirements.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/docs/src/404.rst +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/docs/src/conf.py +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/docs/src/example_library.rst +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/docs/src/examples.rst +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/docs/src/index.rst +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/docs/src/lib.py +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/docs/src/reference.rst +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/docs/src/static/custom.css +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/readme_pypi.rst +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/requirements/build +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/requirements/dev +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/requirements/docs +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/requirements/extras +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/requirements/tests +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/setup.cfg +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/extension/backref.py +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/extension/cache.py +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/extension/directive.py +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/extension/translation.py +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/de/LC_MESSAGES/sphinx-codeautolink.mo +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/de/LC_MESSAGES/sphinx-codeautolink.po +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/es/LC_MESSAGES/sphinx-codeautolink.mo +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/es/LC_MESSAGES/sphinx-codeautolink.po +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/fi/LC_MESSAGES/sphinx-codeautolink.mo +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/fi/LC_MESSAGES/sphinx-codeautolink.po +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/fr/LC_MESSAGES/sphinx-codeautolink.mo +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/fr/LC_MESSAGES/sphinx-codeautolink.po +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/it/LC_MESSAGES/sphinx-codeautolink.mo +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/it/LC_MESSAGES/sphinx-codeautolink.po +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/nl/LC_MESSAGES/sphinx-codeautolink.mo +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/nl/LC_MESSAGES/sphinx-codeautolink.po +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/ru/LC_MESSAGES/sphinx-codeautolink.po +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/sphinx-codeautolink.pot +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/locale/uk/LC_MESSAGES/sphinx-codeautolink.po +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/static/sphinx-codeautolink.css +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/warn.py +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink.egg-info/dependency_links.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink.egg-info/requires.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink.egg-info/top_level.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/__init__.py +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/__init__.py +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/_check.py +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/fail/concat_invalid.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/fail/custom_block_import_invalid.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/fail/custom_block_syntax_error.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/fail/failed_resolve_invalid_location.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/fail/failed_resolve_no_module.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/fail/failed_resolve_return_type.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/fail/match_block_warning.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/fail/missing_inventory.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/fail/no_backreference.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/fail/no_module_docs.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/fail/preface_invalid_arg.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/fail/ref_import_star_invalid.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/fail/ref_invalid_block_type.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/fail/ref_invalid_syntax.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/fail/ref_invalid_syntax_complex.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/fail/ref_ipython_non-python.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/fail/skip_invalid.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/class_mro_fix.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/concat_default.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/concat_off.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/concat_on_across_sections.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/concat_on_breaks.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/concat_section_breaks.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/concat_section_returns_to_global.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/custom_block.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/custom_block_imported.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/empty_project.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/inventory_map_is_needed.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/inventory_map_not_needed.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_bazel.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_default.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_default_fail.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_doctest.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_doctest_empty_input.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_extdoctest_doctest.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_extdoctest_setup.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_extdoctest_setup_wrong.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_extdoctest_testcode.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_highlight_language.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_highlight_none.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_ipython.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_ipython3.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_ipython_directive.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_ipython_directive_comment.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_ipython_syntax.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_literal.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_non_python_block.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_py.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_py3.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_pycon.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_pycon_implicit.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_pyi.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_python3.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_sage.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/lexer_starlark.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/line_numbers.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/preface_concatenated.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/preface_consumed_non_python.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/preface_document.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/preface_global.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/preface_global_multiline.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/preface_global_overwritten.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/preface_multiline.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/preface_multiline_and_arg.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/preface_multiple.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/preface_single.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_assign_targets.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_builtins.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_chain.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_chain_call.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_class_attr.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_class_meth_returns_self.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_class_type_attr.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_decorator.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_fluent_attrs.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_fluent_call.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_func_args.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_func_no_module.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_import_as.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_import_from.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_import_from_complex.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_import_multiple.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_import_multiple_libs.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_import_star.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_import_submodule.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_imported_func.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_imported_func_relocated.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_inherited.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_intersphinx_only.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_invalid_func.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_invalid_typehint.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_optional.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_optional_future.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_shadow_builtin.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/ref_simple.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/search_css_duplicates_removed.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/skip_file.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/skip_next.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/skip_next_consumed_non_python.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/skip_off.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/ref/skip_section.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/src/class_mro_fix.py +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/src/parser_func.py +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/src/test_project/sub.py +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/table/tab_autodoc_empty.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/table/tab_autodoc_links.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/table/tab_manual_collapse.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/table/tab_manual_empty.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/table/tab_manual_links.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/table/tab_manual_links_subsection.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/extension/table/tab_no_table.txt +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/parse/__init__.py +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/parse/_util.py +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/parse/chain.py +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/parse/match.py +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tests/parse/scope.py +0 -0
- {sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/tox.ini +0 -0
|
@@ -1,31 +1,9 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
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>
|
|
7
|
-
License: MIT License
|
|
8
|
-
|
|
9
|
-
Copyright (c) 2021-2025 Felix Hildén
|
|
10
|
-
|
|
11
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
13
|
-
in the Software without restriction, including without limitation the rights
|
|
14
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
15
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
16
|
-
furnished to do so, subject to the following conditions:
|
|
17
|
-
|
|
18
|
-
The above copyright notice and this permission notice shall be included in all
|
|
19
|
-
copies or substantial portions of the Software.
|
|
20
|
-
|
|
21
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
22
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
23
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
25
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
26
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
27
|
-
SOFTWARE.
|
|
28
|
-
|
|
29
7
|
Project-URL: homepage, https://pypi.org/project/sphinx-codeautolink
|
|
30
8
|
Project-URL: download, https://pypi.org/project/sphinx-codeautolink
|
|
31
9
|
Project-URL: source, https://github.com/felix-hilden/sphinx-codeautolink
|
|
@@ -41,6 +19,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
41
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
42
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
43
21
|
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
44
23
|
Classifier: Topic :: Documentation
|
|
45
24
|
Classifier: Topic :: Documentation :: Sphinx
|
|
46
25
|
Classifier: Topic :: Software Development :: Documentation
|
|
@@ -51,6 +30,7 @@ Requires-Dist: sphinx>=3.2.0
|
|
|
51
30
|
Requires-Dist: beautifulsoup4>=4.8.1
|
|
52
31
|
Provides-Extra: ipython
|
|
53
32
|
Requires-Dist: ipython!=8.7.0; extra == "ipython"
|
|
33
|
+
Dynamic: license-file
|
|
54
34
|
|
|
55
35
|
sphinx-codeautolink
|
|
56
36
|
===================
|
|
@@ -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,19 @@ 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
|
+
|
|
20
|
+
0.17.5 (2025-07-09)
|
|
21
|
+
-------------------
|
|
22
|
+
- Add ``Python`` to default lexers (:issue:`194`)
|
|
23
|
+
|
|
11
24
|
0.17.4 (2025-03-07)
|
|
12
25
|
-------------------
|
|
13
26
|
- Fix backreference links using relative URIs (:issue:`190`)
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["setuptools>=
|
|
2
|
+
requires = ["setuptools>=77.0", "wheel"]
|
|
3
3
|
build-backend = "setuptools.build_meta"
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "sphinx-codeautolink"
|
|
7
7
|
description = "Automatic links from code examples to reference documentation."
|
|
8
8
|
readme = "readme_pypi.rst"
|
|
9
|
-
license =
|
|
9
|
+
license-files = ["LICENSE"]
|
|
10
10
|
dynamic = ["version"]
|
|
11
11
|
|
|
12
12
|
requires-python = ">=3.10"
|
|
@@ -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.4 → 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):
|
|
@@ -52,7 +52,7 @@ def print_exceptions(*, append_source: bool = False):
|
|
|
52
52
|
source = doctree["source"]
|
|
53
53
|
msg = f"in document `{source}`"
|
|
54
54
|
if e.args:
|
|
55
|
-
e.args = (e.args[0] + f" ({msg})",
|
|
55
|
+
e.args = (e.args[0] + f" ({msg})", *e.args[1:])
|
|
56
56
|
else:
|
|
57
57
|
e.args = (f"Unexpected error {msg}",)
|
|
58
58
|
raise
|
{sphinx_codeautolink-0.17.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink/extension/block.py
RENAMED
|
@@ -21,6 +21,7 @@ from .directive import ConcatMarker, PrefaceMarker, SkipMarker
|
|
|
21
21
|
BUILTIN_BLOCKS = {
|
|
22
22
|
"default": None,
|
|
23
23
|
"python": None,
|
|
24
|
+
"Python": None,
|
|
24
25
|
"python3": None,
|
|
25
26
|
"py": None,
|
|
26
27
|
"py3": None,
|
|
@@ -88,7 +89,7 @@ def _exclude_ipython_output(source: str) -> str:
|
|
|
88
89
|
|
|
89
90
|
def clean_ipython(source: str) -> tuple[str, str]:
|
|
90
91
|
"""Clean up IPython magics and console syntax to pure Python."""
|
|
91
|
-
from IPython.core.inputtransformer2 import TransformerManager
|
|
92
|
+
from IPython.core.inputtransformer2 import TransformerManager # noqa: PLC0415
|
|
92
93
|
|
|
93
94
|
clean = _exclude_ipython_output(source)
|
|
94
95
|
return source, TransformerManager().transform_cell(clean)
|
|
@@ -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.4 → sphinx_codeautolink-0.18.0}/src/sphinx_codeautolink.egg-info/PKG-INFO
RENAMED
|
@@ -1,31 +1,9 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
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>
|
|
7
|
-
License: MIT License
|
|
8
|
-
|
|
9
|
-
Copyright (c) 2021-2025 Felix Hildén
|
|
10
|
-
|
|
11
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
13
|
-
in the Software without restriction, including without limitation the rights
|
|
14
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
15
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
16
|
-
furnished to do so, subject to the following conditions:
|
|
17
|
-
|
|
18
|
-
The above copyright notice and this permission notice shall be included in all
|
|
19
|
-
copies or substantial portions of the Software.
|
|
20
|
-
|
|
21
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
22
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
23
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
25
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
26
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
27
|
-
SOFTWARE.
|
|
28
|
-
|
|
29
7
|
Project-URL: homepage, https://pypi.org/project/sphinx-codeautolink
|
|
30
8
|
Project-URL: download, https://pypi.org/project/sphinx-codeautolink
|
|
31
9
|
Project-URL: source, https://github.com/felix-hilden/sphinx-codeautolink
|
|
@@ -41,6 +19,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
41
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
42
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
43
21
|
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
44
23
|
Classifier: Topic :: Documentation
|
|
45
24
|
Classifier: Topic :: Documentation :: Sphinx
|
|
46
25
|
Classifier: Topic :: Software Development :: Documentation
|
|
@@ -51,6 +30,7 @@ Requires-Dist: sphinx>=3.2.0
|
|
|
51
30
|
Requires-Dist: beautifulsoup4>=4.8.1
|
|
52
31
|
Provides-Extra: ipython
|
|
53
32
|
Requires-Dist: ipython!=8.7.0; extra == "ipython"
|
|
33
|
+
Dynamic: license-file
|
|
54
34
|
|
|
55
35
|
sphinx-codeautolink
|
|
56
36
|
===================
|
|
@@ -83,6 +83,7 @@ tests/extension/ref/custom_block_imported.txt
|
|
|
83
83
|
tests/extension/ref/empty_project.txt
|
|
84
84
|
tests/extension/ref/inventory_map_is_needed.txt
|
|
85
85
|
tests/extension/ref/inventory_map_not_needed.txt
|
|
86
|
+
tests/extension/ref/lexer_Python.txt
|
|
86
87
|
tests/extension/ref/lexer_bazel.txt
|
|
87
88
|
tests/extension/ref/lexer_default.txt
|
|
88
89
|
tests/extension/ref/lexer_default_fail.txt
|
|
@@ -130,6 +131,7 @@ tests/extension/ref/ref_class_type_attr.txt
|
|
|
130
131
|
tests/extension/ref/ref_decorator.txt
|
|
131
132
|
tests/extension/ref/ref_fluent_attrs.txt
|
|
132
133
|
tests/extension/ref/ref_fluent_call.txt
|
|
134
|
+
tests/extension/ref/ref_for_loop.txt
|
|
133
135
|
tests/extension/ref/ref_func_args.txt
|
|
134
136
|
tests/extension/ref/ref_func_no_module.txt
|
|
135
137
|
tests/extension/ref/ref_import_as.txt
|
|
@@ -145,10 +147,14 @@ tests/extension/ref/ref_inherited.txt
|
|
|
145
147
|
tests/extension/ref/ref_intersphinx_only.txt
|
|
146
148
|
tests/extension/ref/ref_invalid_func.txt
|
|
147
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
|
|
148
153
|
tests/extension/ref/ref_optional.txt
|
|
149
154
|
tests/extension/ref/ref_optional_future.txt
|
|
150
155
|
tests/extension/ref/ref_shadow_builtin.txt
|
|
151
156
|
tests/extension/ref/ref_simple.txt
|
|
157
|
+
tests/extension/ref/ref_type_checking_gated.txt
|
|
152
158
|
tests/extension/ref/search_css_duplicates_removed.txt
|
|
153
159
|
tests/extension/ref/skip_file.txt
|
|
154
160
|
tests/extension/ref/skip_next.txt
|
|
@@ -160,6 +166,8 @@ tests/extension/src/future_project.py
|
|
|
160
166
|
tests/extension/src/parser_func.py
|
|
161
167
|
tests/extension/src/test_project/__init__.py
|
|
162
168
|
tests/extension/src/test_project/sub.py
|
|
169
|
+
tests/extension/src/type_checking/__init__.py
|
|
170
|
+
tests/extension/src/type_checking/foo.py
|
|
163
171
|
tests/extension/table/tab_autodoc_empty.txt
|
|
164
172
|
tests/extension/table/tab_autodoc_links.txt
|
|
165
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
|