Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create a new type for the current document's environment state #13151

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

AA-Turner
Copy link
Member

Feature or Bugfix

  • Refactoring

Purpose

As a step towards #13072, this PR introduces a new CurrentDocument type to store and manipulate state in the environment for the document currently being read. This is currently stored in a temp_data dict.

We also rename the attribute on BuildEnvironment to current_document from temp_data, keeping the old name as an alias.

At present, none of the old names or e.g. the mapping interface to CurrentDocument are deprecated, though I expect that in the future this would be done.

For downstream extensions that make use of env.temp_data['...'], this should be a transparent refactor.

xref:

@AA-Turner AA-Turner added this to the 8.2.0 milestone Nov 22, 2024
Copy link
Member

@picnixz picnixz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This kind of interface, while being transparent for the user, may be worth documenting for extension developers
The class wouldn't be exposed but we can expose each documented attribute.

@@ -635,7 +640,7 @@ def read_doc(self, docname: str, *, _cache: bool = True) -> None:
self.env.all_docs[docname] = time.time_ns() // 1_000

# cleanup
self.env.temp_data.clear()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should keep this one if people add stuff in their own temp_data and expect it to be cleaned up.

@@ -420,7 +420,7 @@ class CNamespacePopObject(SphinxDirective):
option_spec: ClassVar[OptionSpec] = {}

def run(self) -> list[Node]:
stack = self.env.temp_data.get('c:namespace_stack', None)
stack = self.env.current_document.get('c:namespace_stack', None)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
stack = self.env.current_document.get('c:namespace_stack', None)
stack = self.env.current_document.get('c:namespace_stack')

@@ -659,7 +659,7 @@ def run(self) -> tuple[list[Node], list[system_message]]:
location=self.get_location())
# see below
return [addnodes.desc_inline('c', text, text, classes=[self.class_type])], []
parentSymbol = self.env.temp_data.get('c:parent_symbol', None)
parentSymbol = self.env.current_document.get('c:parent_symbol', None)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
parentSymbol = self.env.current_document.get('c:parent_symbol', None)
parentSymbol = self.env.current_document.get('c:parent_symbol')

@@ -123,7 +123,7 @@ def changesets(self) -> dict[str, list[ChangeSet]]:
def note_changeset(self, node: addnodes.versionmodified) -> None:
version = node['version']
module = self.env.ref_context.get('py:module')
objname = self.env.temp_data.get('object', '')
objname = self.env.current_document.obj_desc_name
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now this can be None instead of ''. Wouldn't it still be acceptable as an input to the ChangeSet object constructed just after?

@@ -537,14 +540,14 @@ def run(self) -> list[Node]:
logger.warning(e, location=self.get_location())
name = _make_phony_error_name()
ast = ASTNamespace(name, None)
oldParent = self.env.temp_data.get('cpp:parent_symbol', None)
oldParent = self.env.current_document.get('cpp:parent_symbol', None)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
oldParent = self.env.current_document.get('cpp:parent_symbol', None)
oldParent = self.env.current_document.get('cpp:parent_symbol')

I won't do it for the next usages but I think we can just remove all None defaults.

return default

def pop(self, key: str, default: Any | None = None) -> Any | None:
if key == 'annotations':
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about a static dict mapping aliases to normalized keys? (it would reduce the big if duplication. You could also store in this static dict whether the attribute can be popped or not)

@@ -842,3 +860,208 @@ def _check_toc_parents(toctree_includes: dict[str, list[str]]) -> None:
type='toc',
subtype='multiple_toc_parents',
)


class _CurrentDocument:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could make it inherit from MutableMapping to help linters perhaps.

def new_serial_number(self, category: str = '', /) -> int:
"""Return a serial number, e.g. for index entry targets.

The number is guaranteed to be unique in the current document.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and category

self._serial_numbers: dict[str, int] = {}

# Stores properties relating to the current document set by extensions.
self._ext_props: dict[str, Any] = {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe extras instead? Shorter and kind of self-explanatory as well IMO.

Maybe you could add a property returning a proxy on the extras properties as well (may be useful for extensions to see if they can or cannot override something)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants