pdoc 14.6.1__tar.gz → 14.7.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.
Files changed (74) hide show
  1. {pdoc-14.6.1 → pdoc-14.7.0}/CHANGELOG.md +10 -0
  2. {pdoc-14.6.1/pdoc.egg-info → pdoc-14.7.0}/PKG-INFO +2 -1
  3. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/__init__.py +1 -1
  4. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/doc.py +14 -4
  5. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/doc_ast.py +8 -8
  6. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/render_helpers.py +15 -6
  7. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/default/module.html.jinja2 +1 -1
  8. {pdoc-14.6.1 → pdoc-14.7.0/pdoc.egg-info}/PKG-INFO +2 -1
  9. {pdoc-14.6.1 → pdoc-14.7.0}/pyproject.toml +1 -0
  10. {pdoc-14.6.1 → pdoc-14.7.0}/test/test_doc.py +8 -7
  11. {pdoc-14.6.1 → pdoc-14.7.0}/test/test_doc_types.py +3 -1
  12. {pdoc-14.6.1 → pdoc-14.7.0}/test/test_snapshot.py +6 -10
  13. {pdoc-14.6.1 → pdoc-14.7.0}/LICENSE +0 -0
  14. {pdoc-14.6.1 → pdoc-14.7.0}/MANIFEST.in +0 -0
  15. {pdoc-14.6.1 → pdoc-14.7.0}/README.md +0 -0
  16. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/__main__.py +0 -0
  17. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/_compat.py +0 -0
  18. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/doc_pyi.py +0 -0
  19. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/doc_types.py +0 -0
  20. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/docstrings.py +0 -0
  21. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/extract.py +0 -0
  22. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/markdown2/LICENSE +0 -0
  23. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/markdown2/README.md +0 -0
  24. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/markdown2/__init__.py +0 -0
  25. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/py.typed +0 -0
  26. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/render.py +0 -0
  27. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/search.py +0 -0
  28. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/README.md +0 -0
  29. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/build-search-index.js +0 -0
  30. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/content.css +0 -0
  31. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/custom.css +0 -0
  32. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/default/error.html.jinja2 +0 -0
  33. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/default/frame.html.jinja2 +0 -0
  34. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/default/index.html.jinja2 +0 -0
  35. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/deprecated/README.md +0 -0
  36. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/deprecated/bootstrap-reboot.min.css +0 -0
  37. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/deprecated/box-arrow-in-left.svg +0 -0
  38. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/deprecated/elasticlunr.min.js +0 -0
  39. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/deprecated/favicon.svg +0 -0
  40. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/deprecated/navtoggle.svg +0 -0
  41. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/deprecated/pdoc-logo.svg +0 -0
  42. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/deprecated/resources/favicon.svg +0 -0
  43. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/layout.css +0 -0
  44. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/livereload.html.jinja2 +0 -0
  45. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/math.html.jinja2 +0 -0
  46. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/mermaid.html.jinja2 +0 -0
  47. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/resources/bootstrap-reboot.min.css +0 -0
  48. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/resources/box-arrow-in-left.svg +0 -0
  49. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/resources/elasticlunr.min.js +0 -0
  50. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/resources/exclamation-triangle-fill.svg +0 -0
  51. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/resources/info-circle-fill.svg +0 -0
  52. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/resources/lightning-fill.svg +0 -0
  53. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/resources/navtoggle.svg +0 -0
  54. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/resources/pdoc-logo.svg +0 -0
  55. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/search.html.jinja2 +0 -0
  56. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/search.js.jinja2 +0 -0
  57. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/syntax-highlighting.css +0 -0
  58. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/templates/theme.css +0 -0
  59. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc/web.py +0 -0
  60. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc.egg-info/SOURCES.txt +0 -0
  61. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc.egg-info/dependency_links.txt +0 -0
  62. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc.egg-info/entry_points.txt +0 -0
  63. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc.egg-info/requires.txt +0 -0
  64. {pdoc-14.6.1 → pdoc-14.7.0}/pdoc.egg-info/top_level.txt +0 -0
  65. {pdoc-14.6.1 → pdoc-14.7.0}/setup.cfg +0 -0
  66. {pdoc-14.6.1 → pdoc-14.7.0}/test/test_doc_ast.py +0 -0
  67. {pdoc-14.6.1 → pdoc-14.7.0}/test/test_doc_pyi.py +0 -0
  68. {pdoc-14.6.1 → pdoc-14.7.0}/test/test_docstrings.py +0 -0
  69. {pdoc-14.6.1 → pdoc-14.7.0}/test/test_extract.py +0 -0
  70. {pdoc-14.6.1 → pdoc-14.7.0}/test/test_main.py +0 -0
  71. {pdoc-14.6.1 → pdoc-14.7.0}/test/test_render_helpers.py +0 -0
  72. {pdoc-14.6.1 → pdoc-14.7.0}/test/test_search.py +0 -0
  73. {pdoc-14.6.1 → pdoc-14.7.0}/test/test_smoke.py +0 -0
  74. {pdoc-14.6.1 → pdoc-14.7.0}/test/test_web.py +0 -0
@@ -5,6 +5,16 @@
5
5
  ## Unreleased: pdoc next
6
6
 
7
7
 
8
+ ## 11 September 2024: pdoc 14.7.0
9
+
10
+ - Do not shorten `current_module.func` to `func` in docstrings when linking.
11
+ This prevents logical errors in code examples with imports.
12
+ ([#740](https://github.com/mitmproxy/pdoc/pull/740), @mhils)
13
+ - Add support for Python 3.13.
14
+ ([#730](https://github.com/mitmproxy/pdoc/pull/730), @mhils)
15
+ - pdoc now strips `collections.abc.` from type annotations to make them more concise.
16
+ ([#736](https://github.com/mitmproxy/pdoc/pull/736), @mhils)
17
+
8
18
  ## 2024-08-27: pdoc 14.6.1
9
19
 
10
20
  - Fix a bug where entire modules would be excluded by `--no-include-undocumented`.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pdoc
3
- Version: 14.6.1
3
+ Version: 14.7.0
4
4
  Summary: API Documentation for Python Projects
5
5
  Author-email: Maximilian Hils <pdoc@maximilianhils.com>
6
6
  License: MIT-0
@@ -21,6 +21,7 @@ Classifier: Programming Language :: Python :: 3.9
21
21
  Classifier: Programming Language :: Python :: 3.10
22
22
  Classifier: Programming Language :: Python :: 3.11
23
23
  Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: 3.13
24
25
  Classifier: Typing :: Typed
25
26
  Requires-Python: >=3.8
26
27
  Description-Content-Type: text/markdown
@@ -481,7 +481,7 @@ You can find an example in [`examples/library-usage`](https://github.com/mitmpro
481
481
  from __future__ import annotations
482
482
 
483
483
  __docformat__ = "markdown" # explicitly disable rST processing in the examples above.
484
- __version__ = "14.6.1" # this is read from setup.py
484
+ __version__ = "14.7.0" # this is read from setup.py
485
485
 
486
486
  from pathlib import Path
487
487
  from typing import overload
@@ -1132,9 +1132,11 @@ class Variable(Doc[None]):
1132
1132
  if self.default_value is empty:
1133
1133
  return ""
1134
1134
  if isinstance(self.default_value, TypeAliasType):
1135
- return formatannotation(self.default_value.__value__)
1135
+ formatted = formatannotation(self.default_value.__value__)
1136
+ return _remove_collections_abc(formatted)
1136
1137
  elif self.annotation == TypeAlias:
1137
- return formatannotation(self.default_value)
1138
+ formatted = formatannotation(self.default_value)
1139
+ return _remove_collections_abc(formatted)
1138
1140
 
1139
1141
  # This is not perfect, but a solid attempt at preventing accidental leakage of secrets.
1140
1142
  # If you have input on how to improve the heuristic, please send a pull request!
@@ -1166,7 +1168,8 @@ class Variable(Doc[None]):
1166
1168
  def annotation_str(self) -> str:
1167
1169
  """The variable's type annotation as a pretty-printed str."""
1168
1170
  if self.annotation is not empty:
1169
- return f": {formatannotation(self.annotation)}"
1171
+ formatted = formatannotation(self.annotation)
1172
+ return f": {_remove_collections_abc(formatted)}"
1170
1173
  else:
1171
1174
  return ""
1172
1175
 
@@ -1202,6 +1205,7 @@ class _PrettySignature(inspect.Signature):
1202
1205
  for param in self.parameters.values():
1203
1206
  formatted = str(param)
1204
1207
  formatted = _remove_memory_addresses(formatted)
1208
+ formatted = _remove_collections_abc(formatted)
1205
1209
 
1206
1210
  kind = param.kind
1207
1211
 
@@ -1238,7 +1242,8 @@ class _PrettySignature(inspect.Signature):
1238
1242
 
1239
1243
  def _return_annotation_str(self) -> str:
1240
1244
  if self.return_annotation is not empty:
1241
- return formatannotation(self.return_annotation)
1245
+ formatted = formatannotation(self.return_annotation)
1246
+ return _remove_collections_abc(formatted)
1242
1247
  else:
1243
1248
  return ""
1244
1249
 
@@ -1333,3 +1338,8 @@ _Enum_default_docstrings = tuple(
1333
1338
  def _remove_memory_addresses(x: str) -> str:
1334
1339
  """Remove memory addresses from repr() output"""
1335
1340
  return re.sub(r" at 0x[0-9a-fA-F]+(?=>)", "", x)
1341
+
1342
+
1343
+ def _remove_collections_abc(x: str) -> str:
1344
+ """Remove 'collections.abc' from type signatures."""
1345
+ return re.sub(r"(?!\.)\bcollections\.abc\.", "", x)
@@ -240,12 +240,11 @@ def _parse_class(source: str) -> ast.ClassDef:
240
240
  Returns an empty ast.ClassDef if source is empty.
241
241
  """
242
242
  tree = _parse(source)
243
- assert len(tree.body) <= 1
244
- if tree.body:
243
+ if tree.body and len(tree.body) == 1:
245
244
  t = tree.body[0]
246
- assert isinstance(t, ast.ClassDef)
247
- return t
248
- return ast.ClassDef(body=[], decorator_list=[]) # type: ignore
245
+ if isinstance(t, ast.ClassDef):
246
+ return t
247
+ return ast.ClassDef(name="PdocStub", body=[], decorator_list=[]) # type: ignore
249
248
 
250
249
 
251
250
  @cache
@@ -256,8 +255,7 @@ def _parse_function(source: str) -> ast.FunctionDef | ast.AsyncFunctionDef:
256
255
  Returns an empty ast.FunctionDef if source is empty.
257
256
  """
258
257
  tree = _parse(source)
259
- assert len(tree.body) <= 1
260
- if tree.body:
258
+ if tree.body and len(tree.body) == 1:
261
259
  t = tree.body[0]
262
260
  if isinstance(t, (ast.FunctionDef, ast.AsyncFunctionDef)):
263
261
  return t
@@ -265,7 +263,9 @@ def _parse_function(source: str) -> ast.FunctionDef | ast.AsyncFunctionDef:
265
263
  # we have a lambda function,
266
264
  # to simplify the API return the ast.FunctionDef stub.
267
265
  pass
268
- return ast.FunctionDef(body=[], decorator_list=[]) # type: ignore
266
+ return ast.FunctionDef(
267
+ name="pdoc_stub", args=ast.arguments(), body=[], decorator_list=[]
268
+ ) # type: ignore
269
269
 
270
270
 
271
271
  def _parse(
@@ -307,11 +307,17 @@ def module_candidates(identifier: str, current_module: str) -> Iterable[str]:
307
307
 
308
308
 
309
309
  @pass_context
310
- def linkify(context: Context, code: str, namespace: str = "") -> str:
310
+ def linkify(
311
+ context: Context, code: str, namespace: str = "", shorten: bool = True
312
+ ) -> str:
311
313
  """
312
314
  Link all identifiers in a block of text. Identifiers referencing unknown modules or modules that
313
315
  are not rendered at the moment will be ignored.
314
316
  A piece of text is considered to be an identifier if it either contains a `.` or is surrounded by `<code>` tags.
317
+
318
+ If `shorten` is True, replace identifiers with short forms where possible.
319
+ For example, replace "current_module.Foo" with "Foo". This is useful for annotations
320
+ (which are verbose), but undesired for docstrings (where we want to preserve intent).
315
321
  """
316
322
 
317
323
  def linkify_repl(m: re.Match):
@@ -381,12 +387,15 @@ def linkify(context: Context, code: str, namespace: str = "") -> str:
381
387
  and (target_object is doc.obj or target_object is None)
382
388
  and context["is_public"](doc).strip()
383
389
  ):
384
- if module == mod:
385
- url_text = qualname
390
+ if shorten:
391
+ if module == mod:
392
+ url_text = qualname
393
+ else:
394
+ url_text = doc.fullname
395
+ if plain_text.endswith("()"):
396
+ url_text += "()"
386
397
  else:
387
- url_text = doc.fullname
388
- if plain_text.endswith("()"):
389
- url_text += "()"
398
+ url_text = plain_text
390
399
  return f'<a href="{relative_link(context["module"].modulename, doc.modulename)}#{qualname}">{url_text}</a>'
391
400
 
392
401
  # No matches found.
@@ -209,7 +209,7 @@ See https://pdoc.dev/docs/pdoc/render_helpers.html#DefaultMacroExtension for an
209
209
  {% enddefaultmacro %}
210
210
  {% defaultmacro docstring(var) %}
211
211
  {% if var.docstring %}
212
- <div class="docstring">{{ var.docstring | replace("@public", "") | to_markdown | to_html | linkify(namespace=var.qualname) }}</div>
212
+ <div class="docstring">{{ var.docstring | replace("@public", "") | to_markdown | to_html | linkify(namespace=var.qualname, shorten=False) }}</div>
213
213
  {% endif %}
214
214
  {% enddefaultmacro %}
215
215
  {% defaultmacro nav_members(members) %}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pdoc
3
- Version: 14.6.1
3
+ Version: 14.7.0
4
4
  Summary: API Documentation for Python Projects
5
5
  Author-email: Maximilian Hils <pdoc@maximilianhils.com>
6
6
  License: MIT-0
@@ -21,6 +21,7 @@ Classifier: Programming Language :: Python :: 3.9
21
21
  Classifier: Programming Language :: Python :: 3.10
22
22
  Classifier: Programming Language :: Python :: 3.11
23
23
  Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: 3.13
24
25
  Classifier: Typing :: Typed
25
26
  Requires-Python: >=3.8
26
27
  Description-Content-Type: text/markdown
@@ -28,6 +28,7 @@ classifiers = [
28
28
  "Programming Language :: Python :: 3.10",
29
29
  "Programming Language :: Python :: 3.11",
30
30
  "Programming Language :: Python :: 3.12",
31
+ "Programming Language :: Python :: 3.13",
31
32
  "Typing :: Typed",
32
33
  ]
33
34
 
@@ -1,7 +1,6 @@
1
1
  import builtins
2
2
  import dataclasses
3
3
  from pathlib import Path
4
- import sys
5
4
  import types
6
5
  from unittest.mock import patch
7
6
 
@@ -120,13 +119,15 @@ def test_builtin_source():
120
119
  assert m.source_lines is None
121
120
 
122
121
 
123
- @pytest.mark.skipif(sys.version_info < (3, 9), reason="3.9+ only")
124
122
  def test_raising_getdoc():
125
- class Foo:
126
- @classmethod
127
- @property
128
- def __doc__(self):
129
- raise RuntimeError
123
+ class FooMeta(type):
124
+ def __getattribute__(cls, name):
125
+ if name == "__doc__":
126
+ raise RuntimeError
127
+ return super().__getattribute__(name)
128
+
129
+ class Foo(metaclass=FooMeta):
130
+ pass
130
131
 
131
132
  x = Class(Foo.__module__, Foo.__qualname__, Foo, (Foo.__module__, Foo.__qualname__))
132
133
  with pytest.warns(UserWarning, match="inspect.getdoc(.+) raised an exception"):
@@ -50,7 +50,9 @@ def test_eval_fail_import_nonexistent(monkeypatch):
50
50
  lambda _: "import typing\nif typing.TYPE_CHECKING:\n\timport nonexistent_module",
51
51
  )
52
52
  a = types.ModuleType("a")
53
- with pytest.warns(UserWarning, match="No module named 'nonexistent_module'"):
53
+ with pytest.warns(
54
+ UserWarning, match="No module named 'nonexistent_module'|Import of xyz failed"
55
+ ):
54
56
  assert safe_eval_type("xyz", a.__dict__, None, a, "a") == "xyz"
55
57
 
56
58
 
@@ -96,8 +96,9 @@ class Snapshot:
96
96
 
97
97
  snapshots = [
98
98
  Snapshot("ast_parsing"),
99
+ Snapshot("collections_abc", min_version=(3, 9)),
99
100
  Snapshot("demo", min_version=(3, 9)),
100
- Snapshot("enums", min_version=(3, 12)),
101
+ Snapshot("enums", min_version=(3, 13)),
101
102
  Snapshot("flavors_google"),
102
103
  Snapshot("flavors_numpy"),
103
104
  Snapshot("flavors_rst"),
@@ -135,16 +136,10 @@ snapshots = [
135
136
  with_output_directory=True,
136
137
  ),
137
138
  Snapshot("misc"),
138
- Snapshot(
139
- "misc_py39",
140
- min_version=(3, 9),
141
- ),
139
+ Snapshot("misc_py39", min_version=(3, 9)),
142
140
  Snapshot("misc_py310", min_version=(3, 10)),
143
- Snapshot("misc_py311", min_version=(3, 11)),
144
- Snapshot(
145
- "misc_py312",
146
- min_version=(3, 12),
147
- ),
141
+ Snapshot("misc_py312", min_version=(3, 12)),
142
+ Snapshot("misc_py313", min_version=(3, 13)),
148
143
  Snapshot("math_demo", render_options={"math": True}),
149
144
  Snapshot("math_misc", render_options={"math": True}),
150
145
  Snapshot("mermaid_demo", render_options={"mermaid": True}, min_version=(3, 9)),
@@ -164,6 +159,7 @@ snapshots = [
164
159
  Snapshot("pyo3_sample_library", specs=["pdoc_pyo3_sample_library"]),
165
160
  Snapshot("top_level_reimports", ["top_level_reimports"]),
166
161
  Snapshot("type_checking_imports", ["type_checking_imports.main"]),
162
+ Snapshot("typed_dict", min_version=(3, 13)),
167
163
  Snapshot("type_stubs", ["type_stubs"], min_version=(3, 10)),
168
164
  Snapshot(
169
165
  "visibility",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes