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

docs: importable sphinx autodoc aliases #5569

Closed
wants to merge 3 commits into from

Conversation

ltalirz
Copy link
Member

@ltalirz ltalirz commented Jun 15, 2022

Sphinx allows documentation authors to refer to classes, functions, etc.
via a syntax :py:class:aiida.orm.Dict`.

Since 8a5d8017e8cd09d7e477aa41c8a07bb24a35e58, using the top-level
:py:class:aiida.orm.Dictwas broken and only via a syntax:py:class:aiida.orm.nodes.data.dict.Dict continued to
work, breaking the documentation of many AiiDA plugins.

8a5d8017e8cd09d7e477aa41c8a07bb24a35e58 included a workaround (via
sphinx aliases), that was, however, only applied to the aiida-core
documentation. Here, we use the AiiDA sphinxextension to make these
aliases available to plugins as well.

Fixes #5518

@ltalirz
Copy link
Member Author

ltalirz commented Jun 15, 2022

By putting it into the sphinx extension, which has been used in the plugin-cutter for a long time, we should be able to fix this for many existing plugins without any changes necessary on the plugin side.

Sphinx allows documentation authors to refer to classes, functions, etc.
via a syntax `:py:class:`aiida.orm.Dict`.

Since 8a5d8017e8cd09d7e477aa41c8a07bb24a35e58, using the top-level
`:py:class:`aiida.orm.Dict` was broken and only
via a syntax `:py:class:`aiida.orm.nodes.data.dict.Dict` continued to
work, breaking the documentation of many AiiDA plugins.

8a5d8017e8cd09d7e477aa41c8a07bb24a35e58 included a workaround (via
sphinx aliases), that was, however, only applied to the aiida-core
documentation. Here, we use the AiiDA sphinxextension to make these
aliases available to plugins as well.
@ltalirz ltalirz force-pushed the issue-5518-broken-docs branch from 9a743b1 to cc0bfcf Compare June 15, 2022 20:26
@ltalirz ltalirz requested a review from chrisjsewell June 17, 2022 00:03
@chrisjsewell
Copy link
Member

chrisjsewell commented Jun 22, 2022

Heya 👋

I think something like this is definitely a good idea 👍
However, I think it would be better to auto-generate it in some fashion, either dynamically, or statically (e.g. via a pre-commit hook to create a JSON that is added to the aiida-core package)

Something like:

In [18]: from aiida import common, engine, orm
    ...: aliases = {}
    ...: for mod_name, mod in (('aiida.common', common), ('aiida.engine', engine), ('aiida.orm', orm)):
    ...:     for obj_name in mod.__all__:
    ...:          obj = getattr(mod, obj_name)
    ...:          try:
    ...:              aliases[f"{mod_name}.{obj_name}"] = f"{obj.__module__}.{obj.__name__}"
    ...:          except AttributeError:
    ...:              pass
    ...: aliases
Out[18]: 
{'aiida.common.AiidaException': 'aiida.common.exceptions.AiidaException',
 'aiida.common.AttributeDict': 'aiida.common.extendeddicts.AttributeDict',
 'aiida.common.CalcInfo': 'aiida.common.datastructures.CalcInfo',
 'aiida.common.CalcJobState': 'aiida.common.datastructures.CalcJobState',
 'aiida.common.ClosedStorage': 'aiida.common.exceptions.ClosedStorage',
 'aiida.common.CodeInfo': 'aiida.common.datastructures.CodeInfo',
 'aiida.common.CodeRunMode': 'aiida.common.datastructures.CodeRunMode',
 'aiida.common.ConfigurationError': 'aiida.common.exceptions.ConfigurationError',
 'aiida.common.ConfigurationVersionError': 'aiida.common.exceptions.ConfigurationVersionError',
 'aiida.common.ContentNotExistent': 'aiida.common.exceptions.ContentNotExistent',
 'aiida.common.CorruptStorage': 'aiida.common.exceptions.CorruptStorage',
 'aiida.common.DbContentError': 'aiida.common.exceptions.DbContentError',
 'aiida.common.DefaultFieldsAttributeDict': 'aiida.common.extendeddicts.DefaultFieldsAttributeDict',
 'aiida.common.EntryPointError': 'aiida.common.exceptions.EntryPointError',
 'aiida.common.FailedError': 'aiida.common.exceptions.FailedError',
 'aiida.common.FeatureDisabled': 'aiida.common.exceptions.FeatureDisabled',
 'aiida.common.FeatureNotAvailable': 'aiida.common.exceptions.FeatureNotAvailable',
 'aiida.common.FixedFieldsAttributeDict': 'aiida.common.extendeddicts.FixedFieldsAttributeDict',
 'aiida.common.GraphTraversalRule': 'aiida.common.links.GraphTraversalRule',
 'aiida.common.GraphTraversalRules': 'aiida.common.links.GraphTraversalRules',
 'aiida.common.HashingError': 'aiida.common.exceptions.HashingError',
 'aiida.common.IncompatibleStorageSchema': 'aiida.common.exceptions.IncompatibleStorageSchema',
 'aiida.common.InputValidationError': 'aiida.common.exceptions.InputValidationError',
 'aiida.common.IntegrityError': 'aiida.common.exceptions.IntegrityError',
 'aiida.common.InternalError': 'aiida.common.exceptions.InternalError',
 'aiida.common.InvalidEntryPointTypeError': 'aiida.common.exceptions.InvalidEntryPointTypeError',
 'aiida.common.InvalidOperation': 'aiida.common.exceptions.InvalidOperation',
 'aiida.common.LicensingException': 'aiida.common.exceptions.LicensingException',
 'aiida.common.LinkType': 'aiida.common.links.LinkType',
 'aiida.common.LoadingEntryPointError': 'aiida.common.exceptions.LoadingEntryPointError',
 'aiida.common.LockedProfileError': 'aiida.common.exceptions.LockedProfileError',
 'aiida.common.LockingProfileError': 'aiida.common.exceptions.LockingProfileError',
 'aiida.common.MissingConfigurationError': 'aiida.common.exceptions.MissingConfigurationError',
 'aiida.common.MissingEntryPointError': 'aiida.common.exceptions.MissingEntryPointError',
 'aiida.common.ModificationNotAllowed': 'aiida.common.exceptions.ModificationNotAllowed',
 'aiida.common.MultipleEntryPointError': 'aiida.common.exceptions.MultipleEntryPointError',
 'aiida.common.MultipleObjectsError': 'aiida.common.exceptions.MultipleObjectsError',
 'aiida.common.NotExistent': 'aiida.common.exceptions.NotExistent',
 'aiida.common.NotExistentAttributeError': 'aiida.common.exceptions.NotExistentAttributeError',
 'aiida.common.NotExistentKeyError': 'aiida.common.exceptions.NotExistentKeyError',
 'aiida.common.OutputParsingError': 'aiida.common.exceptions.OutputParsingError',
 'aiida.common.ParsingError': 'aiida.common.exceptions.ParsingError',
 'aiida.common.PluginInternalError': 'aiida.common.exceptions.PluginInternalError',
 'aiida.common.ProfileConfigurationError': 'aiida.common.exceptions.ProfileConfigurationError',
 'aiida.common.ProgressReporterAbstract': 'aiida.common.progress_reporter.ProgressReporterAbstract',
 'aiida.common.RemoteOperationError': 'aiida.common.exceptions.RemoteOperationError',
 'aiida.common.StashMode': 'aiida.common.datastructures.StashMode',
 'aiida.common.StorageMigrationError': 'aiida.common.exceptions.StorageMigrationError',
 'aiida.common.StoringNotAllowed': 'aiida.common.exceptions.StoringNotAllowed',
 'aiida.common.TestsNotAllowedError': 'aiida.common.exceptions.TestsNotAllowedError',
 'aiida.common.TransportTaskException': 'aiida.common.exceptions.TransportTaskException',
 'aiida.common.UniquenessError': 'aiida.common.exceptions.UniquenessError',
 'aiida.common.UnsupportedSpeciesError': 'aiida.common.exceptions.UnsupportedSpeciesError',
 'aiida.common.ValidationError': 'aiida.common.exceptions.ValidationError',
 'aiida.common.create_callback': 'aiida.common.progress_reporter.create_callback',
 'aiida.common.get_progress_reporter': 'aiida.common.progress_reporter.get_progress_reporter',
 'aiida.common.override_log_level': 'aiida.common.log.override_log_level',
 'aiida.common.set_progress_bar_tqdm': 'aiida.common.progress_reporter.set_progress_bar_tqdm',
 'aiida.common.set_progress_reporter': 'aiida.common.progress_reporter.set_progress_reporter',
 'aiida.common.validate_link_label': 'aiida.common.links.validate_link_label',
 'aiida.engine.AiiDAPersister': 'aiida.engine.persistence.AiiDAPersister',
 'aiida.engine.Awaitable': 'aiida.engine.processes.workchains.awaitable.Awaitable',
 'aiida.engine.AwaitableAction': 'aiida.engine.processes.workchains.awaitable.AwaitableAction',
 'aiida.engine.AwaitableTarget': 'aiida.engine.processes.workchains.awaitable.AwaitableTarget',
 'aiida.engine.BaseRestartWorkChain': 'aiida.engine.processes.workchains.restart.BaseRestartWorkChain',
 'aiida.engine.CalcJob': 'aiida.engine.processes.calcjobs.calcjob.CalcJob',
 'aiida.engine.CalcJobImporter': 'aiida.engine.processes.calcjobs.importer.CalcJobImporter',
 'aiida.engine.CalcJobOutputPort': 'aiida.engine.processes.ports.CalcJobOutputPort',
 'aiida.engine.CalcJobProcessSpec': 'aiida.engine.processes.process_spec.CalcJobProcessSpec',
 'aiida.engine.DaemonClient': 'aiida.engine.daemon.client.DaemonClient',
 'aiida.engine.ExitCode': 'aiida.engine.processes.exit_code.ExitCode',
 'aiida.engine.ExitCodesNamespace': 'aiida.engine.processes.exit_code.ExitCodesNamespace',
 'aiida.engine.FunctionProcess': 'aiida.engine.processes.functions.FunctionProcess',
 'aiida.engine.InputPort': 'aiida.engine.processes.ports.InputPort',
 'aiida.engine.InterruptableFuture': 'aiida.engine.utils.InterruptableFuture',
 'aiida.engine.JobManager': 'aiida.engine.processes.calcjobs.manager.JobManager',
 'aiida.engine.JobsList': 'aiida.engine.processes.calcjobs.manager.JobsList',
 'aiida.engine.ObjectLoader': 'aiida.engine.persistence.ObjectLoader',
 'aiida.engine.OutputPort': 'plumpy.ports.OutputPort',
 'aiida.engine.PastException': 'aiida.engine.exceptions.PastException',
 'aiida.engine.PortNamespace': 'aiida.engine.processes.ports.PortNamespace',
 'aiida.engine.Process': 'aiida.engine.processes.process.Process',
 'aiida.engine.ProcessBuilder': 'aiida.engine.processes.builder.ProcessBuilder',
 'aiida.engine.ProcessBuilderNamespace': 'aiida.engine.processes.builder.ProcessBuilderNamespace',
 'aiida.engine.ProcessFuture': 'aiida.engine.processes.futures.ProcessFuture',
 'aiida.engine.ProcessHandlerReport': 'aiida.engine.processes.workchains.utils.ProcessHandlerReport',
 'aiida.engine.ProcessSpec': 'aiida.engine.processes.process_spec.ProcessSpec',
 'aiida.engine.ProcessState': 'plumpy.process_states.ProcessState',
 'aiida.engine.Runner': 'aiida.engine.runners.Runner',
 'aiida.engine.ToContext': 'builtins.dict',
 'aiida.engine.WithNonDb': 'aiida.engine.processes.ports.WithNonDb',
 'aiida.engine.WithSerialize': 'aiida.engine.processes.ports.WithSerialize',
 'aiida.engine.WorkChain': 'aiida.engine.processes.workchains.workchain.WorkChain',
 'aiida.engine.append_': 'aiida.engine.processes.workchains.context.append_',
 'aiida.engine.assign_': 'aiida.engine.processes.workchains.context.assign_',
 'aiida.engine.calcfunction': 'aiida.engine.processes.functions.calcfunction',
 'aiida.engine.construct_awaitable': 'aiida.engine.processes.workchains.awaitable.construct_awaitable',
 'aiida.engine.get_object_loader': 'aiida.engine.persistence.get_object_loader',
 'aiida.engine.if_': 'plumpy.workchains.if_',
 'aiida.engine.interruptable_task': 'aiida.engine.utils.interruptable_task',
 'aiida.engine.is_process_function': 'aiida.engine.utils.is_process_function',
 'aiida.engine.process_handler': 'aiida.engine.processes.workchains.utils.process_handler',
 'aiida.engine.run': 'aiida.engine.launch.run',
 'aiida.engine.run_get_node': 'aiida.engine.launch.run_get_node',
 'aiida.engine.run_get_pk': 'aiida.engine.launch.run_get_pk',
 'aiida.engine.submit': 'aiida.engine.launch.submit',
 'aiida.engine.while_': 'plumpy.workchains.while_',
 'aiida.engine.workfunction': 'aiida.engine.processes.functions.workfunction',
 'aiida.orm.AbstractCode': 'aiida.orm.nodes.data.code.abstract.AbstractCode',
 'aiida.orm.AbstractNodeMeta': 'aiida.orm.utils.node.AbstractNodeMeta',
 'aiida.orm.ArrayData': 'aiida.orm.nodes.data.array.array.ArrayData',
 'aiida.orm.AttributeManager': 'aiida.orm.utils.managers.AttributeManager',
 'aiida.orm.AuthInfo': 'aiida.orm.authinfos.AuthInfo',
 'aiida.orm.AutoGroup': 'aiida.orm.groups.AutoGroup',
 'aiida.orm.BandsData': 'aiida.orm.nodes.data.array.bands.BandsData',
 'aiida.orm.BaseType': 'aiida.orm.nodes.data.base.BaseType',
 'aiida.orm.Bool': 'aiida.orm.nodes.data.bool.Bool',
 'aiida.orm.CalcFunctionNode': 'aiida.orm.nodes.process.calculation.calcfunction.CalcFunctionNode',
 'aiida.orm.CalcJobNode': 'aiida.orm.nodes.process.calculation.calcjob.CalcJobNode',
 'aiida.orm.CalcJobResultManager': 'aiida.orm.utils.calcjob.CalcJobResultManager',
 'aiida.orm.CalculationEntityLoader': 'aiida.orm.utils.loaders.CalculationEntityLoader',
 'aiida.orm.CalculationNode': 'aiida.orm.nodes.process.calculation.calculation.CalculationNode',
 'aiida.orm.CifData': 'aiida.orm.nodes.data.cif.CifData',
 'aiida.orm.Code': 'aiida.orm.nodes.data.code.legacy.Code',
 'aiida.orm.CodeEntityLoader': 'aiida.orm.utils.loaders.CodeEntityLoader',
 'aiida.orm.Collection': 'aiida.orm.entities.Collection',
 'aiida.orm.Comment': 'aiida.orm.comments.Comment',
 'aiida.orm.Computer': 'aiida.orm.computers.Computer',
 'aiida.orm.ComputerEntityLoader': 'aiida.orm.utils.loaders.ComputerEntityLoader',
 'aiida.orm.Data': 'aiida.orm.nodes.data.data.Data',
 'aiida.orm.Dict': 'aiida.orm.nodes.data.dict.Dict',
 'aiida.orm.Entity': 'aiida.orm.entities.Entity',
 'aiida.orm.EntityExtras': 'aiida.orm.extras.EntityExtras',
 'aiida.orm.EntityTypes': 'aiida.orm.entities.EntityTypes',
 'aiida.orm.EnumData': 'aiida.orm.nodes.data.enum.EnumData',
 'aiida.orm.Float': 'aiida.orm.nodes.data.float.Float',
 'aiida.orm.FolderData': 'aiida.orm.nodes.data.folder.FolderData',
 'aiida.orm.Group': 'aiida.orm.groups.Group',
 'aiida.orm.GroupEntityLoader': 'aiida.orm.utils.loaders.GroupEntityLoader',
 'aiida.orm.ImportGroup': 'aiida.orm.groups.ImportGroup',
 'aiida.orm.InstalledCode': 'aiida.orm.nodes.data.code.installed.InstalledCode',
 'aiida.orm.Int': 'aiida.orm.nodes.data.int.Int',
 'aiida.orm.JsonableData': 'aiida.orm.nodes.data.jsonable.JsonableData',
 'aiida.orm.Kind': 'aiida.orm.nodes.data.structure.Kind',
 'aiida.orm.KpointsData': 'aiida.orm.nodes.data.array.kpoints.KpointsData',
 'aiida.orm.LinkManager': 'aiida.orm.utils.links.LinkManager',
 'aiida.orm.LinkPair': 'aiida.orm.utils.links.LinkPair',
 'aiida.orm.LinkTriple': 'aiida.orm.utils.links.LinkTriple',
 'aiida.orm.List': 'aiida.orm.nodes.data.list.List',
 'aiida.orm.Log': 'aiida.orm.logs.Log',
 'aiida.orm.Node': 'aiida.orm.nodes.node.Node',
 'aiida.orm.NodeAttributes': 'aiida.orm.nodes.attributes.NodeAttributes',
 'aiida.orm.NodeEntityLoader': 'aiida.orm.utils.loaders.NodeEntityLoader',
 'aiida.orm.NodeLinksManager': 'aiida.orm.utils.managers.NodeLinksManager',
 'aiida.orm.NodeRepository': 'aiida.orm.nodes.repository.NodeRepository',
 'aiida.orm.NumericType': 'aiida.orm.nodes.data.numeric.NumericType',
 'aiida.orm.OrbitalData': 'aiida.orm.nodes.data.orbital.OrbitalData',
 'aiida.orm.OrderSpecifier': 'aiida.orm.logs.OrderSpecifier',
 'aiida.orm.OrmEntityLoader': 'aiida.orm.utils.loaders.OrmEntityLoader',
 'aiida.orm.PortableCode': 'aiida.orm.nodes.data.code.portable.PortableCode',
 'aiida.orm.ProcessNode': 'aiida.orm.nodes.process.process.ProcessNode',
 'aiida.orm.ProjectionData': 'aiida.orm.nodes.data.array.projection.ProjectionData',
 'aiida.orm.QueryBuilder': 'aiida.orm.querybuilder.QueryBuilder',
 'aiida.orm.RemoteData': 'aiida.orm.nodes.data.remote.base.RemoteData',
 'aiida.orm.RemoteStashData': 'aiida.orm.nodes.data.remote.stash.base.RemoteStashData',
 'aiida.orm.RemoteStashFolderData': 'aiida.orm.nodes.data.remote.stash.folder.RemoteStashFolderData',
 'aiida.orm.SinglefileData': 'aiida.orm.nodes.data.singlefile.SinglefileData',
 'aiida.orm.Site': 'aiida.orm.nodes.data.structure.Site',
 'aiida.orm.Str': 'aiida.orm.nodes.data.str.Str',
 'aiida.orm.StructureData': 'aiida.orm.nodes.data.structure.StructureData',
 'aiida.orm.TrajectoryData': 'aiida.orm.nodes.data.array.trajectory.TrajectoryData',
 'aiida.orm.UpfData': 'aiida.orm.nodes.data.upf.UpfData',
 'aiida.orm.UpfFamily': 'aiida.orm.groups.UpfFamily',
 'aiida.orm.User': 'aiida.orm.users.User',
 'aiida.orm.WorkChainNode': 'aiida.orm.nodes.process.workflow.workchain.WorkChainNode',
 'aiida.orm.WorkFunctionNode': 'aiida.orm.nodes.process.workflow.workfunction.WorkFunctionNode',
 'aiida.orm.WorkflowNode': 'aiida.orm.nodes.process.workflow.workflow.WorkflowNode',
 'aiida.orm.XyData': 'aiida.orm.nodes.data.array.xy.XyData',
 'aiida.orm.cif_from_ase': 'aiida.orm.nodes.data.cif.cif_from_ase',
 'aiida.orm.find_bandgap': 'aiida.orm.nodes.data.array.bands.find_bandgap',
 'aiida.orm.get_loader': 'aiida.orm.utils.loaders.get_loader',
 'aiida.orm.get_query_type_from_type_string': 'aiida.orm.utils.node.get_query_type_from_type_string',
 'aiida.orm.get_type_string_from_class': 'aiida.orm.utils.node.get_type_string_from_class',
 'aiida.orm.has_pycifrw': 'aiida.orm.nodes.data.cif.has_pycifrw',
 'aiida.orm.load_code': 'aiida.orm.utils.loaders.load_code',
 'aiida.orm.load_computer': 'aiida.orm.utils.loaders.load_computer',
 'aiida.orm.load_entity': 'aiida.orm.utils.loaders.load_entity',
 'aiida.orm.load_group': 'aiida.orm.utils.loaders.load_group',
 'aiida.orm.load_node': 'aiida.orm.utils.loaders.load_node',
 'aiida.orm.load_node_class': 'aiida.orm.utils.node.load_node_class',
 'aiida.orm.pycifrw_from_cif': 'aiida.orm.nodes.data.cif.pycifrw_from_cif',
 'aiida.orm.to_aiida_type': 'aiida.orm.nodes.data.base.to_aiida_type',
 'aiida.orm.validate_link': 'aiida.orm.utils.links.validate_link'}

(note, one thing missing here is the determination of what type of reference it is, e.g. py:obj, py:exc, etc)

Copy link
Member

@chrisjsewell chrisjsewell left a comment

Choose a reason for hiding this comment

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

see comment

@ltalirz
Copy link
Member Author

ltalirz commented Jun 22, 2022

Hey @chrisjsewell , feel free to edit the PR!

If you don't have time, this can also be fixed in a later step - let's first get the docs of plugins working again.

@ltalirz
Copy link
Member Author

ltalirz commented Sep 23, 2022

should be fixed by #5657

@ltalirz ltalirz closed this Sep 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Docs: Intersphinx references require fully qualified name for 2.0 documentation
2 participants