aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/_static/custom.js8
-rw-r--r--docs/_static/style.css25
-rw-r--r--docs/api.rst209
-rw-r--r--docs/conf.py3
-rw-r--r--docs/extensions/attributetable.py199
5 files changed, 440 insertions, 4 deletions
diff --git a/docs/_static/custom.js b/docs/_static/custom.js
index 235a14ea..0f1ea7fc 100644
--- a/docs/_static/custom.js
+++ b/docs/_static/custom.js
@@ -27,5 +27,13 @@ $(document).ready(function () {
activeLink = $('.sphinxsidebar a[href="#' + currentSection.attr('id') + '"]');
activeLink.parent().addClass('active');
}
+
+ const tables = document.querySelectorAll('.py-attribute-table[data-move-to-id]');
+ tables.forEach(table => {
+ let element = document.getElementById(table.getAttribute('data-move-to-id'));
+ let parent = element.parentNode;
+ // insert ourselves after the element
+ parent.insertBefore(table, element.nextSibling);
+ });
});
});
diff --git a/docs/_static/style.css b/docs/_static/style.css
index 43966db8..d371518c 100644
--- a/docs/_static/style.css
+++ b/docs/_static/style.css
@@ -278,6 +278,12 @@ div.attention, div.warning, div.caution, div.seealso {
border: 1px solid #fbe091;
}
+dl.field-list > dd {
+ margin-top: 3px;
+ margin-bottom: 10px;
+ margin-left: 20px;
+}
+
/* no disgusting background in the FAQ */
div.topic {
background-color: transparent;
@@ -352,6 +358,25 @@ div.helpful > p.admonition-title:after {
list-style: 'ยป' !important;
}
+/* attribute tables */
+.py-attribute-table {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ margin: 0 2em;
+ padding-top: 16px;
+}
+
+.py-attribute-table-column > span {
+ font-weight: bold;
+}
+
+div.body .py-attribute-table-column > ul {
+ list-style: none;
+ margin: 4px 0px;
+ padding-left: 12px;
+}
+
pre {
background-color: #f5f5f5;
border: 1px solid #C6C9CB;
diff --git a/docs/api.rst b/docs/api.rst
index 695f81ef..516be690 100644
--- a/docs/api.rst
+++ b/docs/api.rst
@@ -30,48 +30,116 @@ There are two main ways to query version information about the library. For guar
A string representation of the version. e.g. ``'1.0.0rc1'``. This is based
off of :pep:`440`.
+Clients
+--------
+
Client
--------
+~~~~~~~
+
+.. attributetable:: Client
.. autoclass:: Client
:members:
+AutoShardedClient
+~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: AutoShardedClient
+
.. autoclass:: AutoShardedClient
:members:
+Application Info
+------------------
+
+AppInfo
+~~~~~~~~
+
+.. attributetable:: AppInfo
+
.. autoclass:: AppInfo()
:members:
+Team
+~~~~~
+
+.. attributetable:: Team
+
.. autoclass:: Team()
:members:
+TeamMember
+~~~~~~~~~~~
+
+.. attributetable:: TeamMember
+
.. autoclass:: TeamMember()
:members:
-Voice
-------
+Voice Related
+---------------
+
+VoiceClient
+~~~~~~~~~~~~
+
+.. attributetable:: VoiceClient
.. autoclass:: VoiceClient()
:members:
+VoiceProtocol
+~~~~~~~~~~~~~~~
+
+.. attributetable:: VoiceProtocol
+
.. autoclass:: VoiceProtocol
:members:
+AudioSource
+~~~~~~~~~~~~
+
+.. attributetable:: AudioSource
+
.. autoclass:: AudioSource
:members:
+PCMAudio
+~~~~~~~~~
+
+.. attributetable:: PCMAudio
+
.. autoclass:: PCMAudio
:members:
+FFmpegAudio
+~~~~~~~~~~~~
+
+.. attributetable:: FFmpegAudio
+
.. autoclass:: FFmpegAudio
:members:
+FFmpegPCMAudio
+~~~~~~~~~~~~~~~
+
+.. attributetable:: FFmpegPCMAudio
+
.. autoclass:: FFmpegPCMAudio
:members:
+FFmpegOpusAudio
+~~~~~~~~~~~~~~~~
+
+.. attributetable:: FFmpegOpusAudio
+
.. autoclass:: FFmpegOpusAudio
:members:
+PCMVolumeTransformer
+~~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: PCMVolumeTransformer
+
.. autoclass:: PCMVolumeTransformer
:members:
@@ -2149,9 +2217,19 @@ Working with :meth:`Guild.audit_logs` is a complicated process with a lot of mac
involved. The library attempts to make it easy to use and friendly. In order to accomplish
this goal, it must make use of a couple of data classes that aid in this goal.
+AuditLogEntry
+~~~~~~~~~~~~~~~
+
+.. attributetable:: AuditLogEntry
+
.. autoclass:: AuditLogEntry
:members:
+AuditLogChanges
+~~~~~~~~~~~~~~~~~
+
+.. attributetable:: AuditLogChanges
+
.. class:: AuditLogChanges
An audit log change set.
@@ -2196,6 +2274,11 @@ this goal, it must make use of a couple of data classes that aid in this goal.
| ``None`` | No attributes are set. |
+----------------------------------------+--------------------------------------------------+
+AuditLogDiff
+~~~~~~~~~~~~~
+
+.. attributetable:: AuditLogDiff
+
.. class:: AuditLogDiff
Represents an audit log "change" object. A change object has dynamic
@@ -2541,6 +2624,8 @@ Webhook Support
discord.py offers support for creating, editing, and executing webhooks through the :class:`Webhook` class.
+.. attributetable:: Webhook
+
.. autoclass:: Webhook
:members:
@@ -2575,18 +2660,43 @@ They are mainly there for usage with :func:`py:isinstance` and :func:`py:issubcl
This library has a module related to abstract base classes, some of which are actually from the :doc:`abc <py:library/abc>` standard
module, others which are not.
+Snowflake
+~~~~~~~~~~
+
+.. attributetable:: discord.abc.Snowflake
+
.. autoclass:: discord.abc.Snowflake
:members:
+User
+~~~~~
+
+.. attributetable:: discord.abc.User
+
.. autoclass:: discord.abc.User
:members:
+PrivateChannel
+~~~~~~~~~~~~~~~
+
+.. attributetable:: discord.abc.PrivateChannel
+
.. autoclass:: discord.abc.PrivateChannel
:members:
+GuildChannel
+~~~~~~~~~~~~~
+
+.. attributetable:: discord.abc.GuildChannel
+
.. autoclass:: discord.abc.GuildChannel
:members:
+Messageable
+~~~~~~~~~~~~
+
+.. attributetable:: discord.abc.Messageable
+
.. autoclass:: discord.abc.Messageable
:members:
:exclude-members: history, typing
@@ -2597,6 +2707,11 @@ module, others which are not.
.. automethod:: discord.abc.Messageable.typing
:async-with:
+Connectable
+~~~~~~~~~~~~
+
+.. attributetable:: discord.abc.Connectable
+
.. autoclass:: discord.abc.Connectable
.. _discord_api_models:
@@ -2629,6 +2744,8 @@ the user of the library.
ClientUser
~~~~~~~~~~~~
+.. attributetable:: ClientUser
+
.. autoclass:: ClientUser()
:members:
:inherited-members:
@@ -2636,12 +2753,16 @@ ClientUser
Relationship
~~~~~~~~~~~~~~
+.. attributetable:: Relationship
+
.. autoclass:: Relationship()
:members:
User
~~~~~
+.. attributetable:: User
+
.. autoclass:: User()
:members:
:inherited-members:
@@ -2656,18 +2777,24 @@ User
Attachment
~~~~~~~~~~~
+.. attributetable:: Attachment
+
.. autoclass:: Attachment()
:members:
Asset
~~~~~
+.. attributetable:: Asset
+
.. autoclass:: Asset()
:members:
Message
~~~~~~~
+.. attributetable:: Message
+
.. autoclass:: Message()
:members:
@@ -2681,6 +2808,8 @@ DeletedReferencedMessage
Reaction
~~~~~~~~~
+.. attributetable:: Reaction
+
.. autoclass:: Reaction()
:members:
:exclude-members: users
@@ -2691,18 +2820,24 @@ Reaction
CallMessage
~~~~~~~~~~~~
+.. attributetable:: CallMessage
+
.. autoclass:: CallMessage()
:members:
GroupCall
~~~~~~~~~~
+.. attributetable:: GroupCall
+
.. autoclass:: GroupCall()
:members:
Guild
~~~~~~
+.. attributetable:: Guild
+
.. autoclass:: Guild()
:members:
:exclude-members: audit_logs
@@ -2722,6 +2857,8 @@ Integration
Member
~~~~~~
+.. attributetable:: Member
+
.. autoclass:: Member()
:members:
:inherited-members:
@@ -2736,30 +2873,40 @@ Member
Spotify
~~~~~~~~
+.. attributetable:: Spotify
+
.. autoclass:: Spotify()
:members:
VoiceState
~~~~~~~~~~~
+.. attributetable:: VoiceState
+
.. autoclass:: VoiceState()
:members:
Emoji
~~~~~
+.. attributetable:: Emoji
+
.. autoclass:: Emoji()
:members:
PartialEmoji
~~~~~~~~~~~~~~~~~~~~~~
+.. attributetable:: PartialEmoji
+
.. autoclass:: PartialEmoji()
:members:
Role
~~~~~
+.. attributetable:: Role
+
.. autoclass:: Role()
:members:
@@ -2772,6 +2919,8 @@ RoleTags
TextChannel
~~~~~~~~~~~~
+.. attributetable:: TextChannel
+
.. autoclass:: TextChannel()
:members:
:inherited-members:
@@ -2786,6 +2935,8 @@ TextChannel
VoiceChannel
~~~~~~~~~~~~~
+.. attributetable:: VoiceChannel
+
.. autoclass:: VoiceChannel()
:members:
:inherited-members:
@@ -2793,6 +2944,8 @@ VoiceChannel
CategoryChannel
~~~~~~~~~~~~~~~~~
+.. attributetable:: CategoryChannel
+
.. autoclass:: CategoryChannel()
:members:
:inherited-members:
@@ -2800,6 +2953,8 @@ CategoryChannel
DMChannel
~~~~~~~~~
+.. attributetable:: DMChannel
+
.. autoclass:: DMChannel()
:members:
:inherited-members:
@@ -2814,6 +2969,8 @@ DMChannel
GroupChannel
~~~~~~~~~~~~
+.. attributetable:: GroupChannel
+
.. autoclass:: GroupChannel()
:members:
:inherited-members:
@@ -2828,18 +2985,24 @@ GroupChannel
PartialInviteGuild
~~~~~~~~~~~~~~~~~~~
+.. attributetable:: PartialInviteGuild
+
.. autoclass:: PartialInviteGuild()
:members:
PartialInviteChannel
~~~~~~~~~~~~~~~~~~~~~
+.. attributetable:: PartialInviteChannel
+
.. autoclass:: PartialInviteChannel()
:members:
Invite
~~~~~~~
+.. attributetable:: Invite
+
.. autoclass:: Invite()
:members:
@@ -2852,12 +3015,16 @@ Template
WidgetChannel
~~~~~~~~~~~~~~~
+.. attributetable:: WidgetChannel
+
.. autoclass:: WidgetChannel()
:members:
WidgetMember
~~~~~~~~~~~~~
+.. attributetable:: WidgetMember
+
.. autoclass:: WidgetMember()
:members:
:inherited-members:
@@ -2865,6 +3032,8 @@ WidgetMember
Widget
~~~~~~~
+.. attributetable:: Widget
+
.. autoclass:: Widget()
:members:
@@ -2877,36 +3046,48 @@ Sticker
RawMessageDeleteEvent
~~~~~~~~~~~~~~~~~~~~~~~
+.. attributetable:: RawMessageDeleteEvent
+
.. autoclass:: RawMessageDeleteEvent()
:members:
RawBulkMessageDeleteEvent
~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. attributetable:: RawBulkMessageDeleteEvent
+
.. autoclass:: RawBulkMessageDeleteEvent()
:members:
RawMessageUpdateEvent
~~~~~~~~~~~~~~~~~~~~~~
+.. attributetable:: RawMessageUpdateEvent
+
.. autoclass:: RawMessageUpdateEvent()
:members:
RawReactionActionEvent
~~~~~~~~~~~~~~~~~~~~~~~
+.. attributetable:: RawReactionActionEvent
+
.. autoclass:: RawReactionActionEvent()
:members:
RawReactionClearEvent
~~~~~~~~~~~~~~~~~~~~~~
+.. attributetable:: RawReactionClearEvent
+
.. autoclass:: RawReactionClearEvent()
:members:
RawReactionClearEmojiEvent
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. attributetable:: RawReactionClearEmojiEvent
+
.. autoclass:: RawReactionClearEmojiEvent()
:members:
@@ -2937,12 +3118,16 @@ Object
Embed
~~~~~~
+.. attributetable:: Embed
+
.. autoclass:: Embed
:members:
AllowedMentions
~~~~~~~~~~~~~~~~~
+.. attributetable:: AllowedMentions
+
.. autoclass:: AllowedMentions
:members:
@@ -2973,54 +3158,72 @@ MemberCacheFlags
File
~~~~~
+.. attributetable:: File
+
.. autoclass:: File
:members:
Colour
~~~~~~
+.. attributetable:: Colour
+
.. autoclass:: Colour
:members:
BaseActivity
~~~~~~~~~~~~~~
+.. attributetable:: BaseActivity
+
.. autoclass:: BaseActivity
:members:
Activity
~~~~~~~~~
+.. attributetable:: Activity
+
.. autoclass:: Activity
:members:
Game
~~~~~
+.. attributetable:: Game
+
.. autoclass:: Game
:members:
Streaming
~~~~~~~~~~~
+.. attributetable:: Streaming
+
.. autoclass:: Streaming
:members:
CustomActivity
~~~~~~~~~~~~~~~
+.. attributetable:: CustomActivity
+
.. autoclass:: CustomActivity
:members:
Permissions
~~~~~~~~~~~~
+.. attributetable:: Permissions
+
.. autoclass:: Permissions
:members:
PermissionOverwrite
~~~~~~~~~~~~~~~~~~~~
+.. attributetable:: PermissionOverwrite
+
.. autoclass:: PermissionOverwrite
:members:
diff --git a/docs/conf.py b/docs/conf.py
index d87049ac..feedd553 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -38,7 +38,8 @@ extensions = [
'sphinx.ext.napoleon',
'sphinxcontrib_trio',
'details',
- 'exception_hierarchy'
+ 'exception_hierarchy',
+ 'attributetable',
]
autodoc_member_order = 'bysource'
diff --git a/docs/extensions/attributetable.py b/docs/extensions/attributetable.py
new file mode 100644
index 00000000..234f944f
--- /dev/null
+++ b/docs/extensions/attributetable.py
@@ -0,0 +1,199 @@
+from sphinx.util.docutils import SphinxDirective
+from sphinx.locale import _
+from docutils import nodes
+from sphinx import addnodes
+
+from collections import OrderedDict
+import importlib
+import inspect
+import os
+import re
+
+class attributetable(nodes.General, nodes.Element):
+ pass
+
+class attributetablecolumn(nodes.General, nodes.Element):
+ pass
+
+class attributetabletitle(nodes.TextElement):
+ pass
+
+class attributetableplaceholder(nodes.General, nodes.Element):
+ pass
+
+def visit_attributetable_node(self, node):
+ self.body.append('<div class="py-attribute-table" data-move-to-id="%s">' % node['python-class'])
+
+def visit_attributetablecolumn_node(self, node):
+ self.body.append(self.starttag(node, 'div', CLASS='py-attribute-table-column'))
+
+def visit_attributetabletitle_node(self, node):
+ self.body.append(self.starttag(node, 'span'))
+
+def depart_attributetable_node(self, node):
+ self.body.append('</div>')
+
+def depart_attributetablecolumn_node(self, node):
+ self.body.append('</div>')
+
+def depart_attributetabletitle_node(self, node):
+ self.body.append('</span>')
+
+_name_parser_regex = re.compile(r'(?P<module>[\w.]+\.)?(?P<name>\w+)')
+
+class PyAttributeTable(SphinxDirective):
+ has_content = False
+ required_arguments = 1
+ optional_arguments = 0
+ final_argument_whitespace = False
+ option_spec = {}
+
+ def parse_name(self, content):
+ path, name = _name_parser_regex.match(content).groups()
+ if path:
+ modulename = path.rstrip('.')
+ else:
+ modulename = self.env.temp_data.get('autodoc:module')
+ if not modulename:
+ modulename = self.env.ref_context.get('py:module')
+ if modulename is None:
+ raise RuntimeError('modulename somehow None for %s in %s.' % (content, self.env.docname))
+
+ return modulename, name
+
+ def run(self):
+ """If you're curious on the HTML this is meant to generate:
+
+ <div class="py-attribute-table">
+ <div class="py-attribute-table-column">
+ <span>_('Attributes')</span>
+ <ul>
+ <li><a href="..."></li>
+ </ul>
+ </div>
+ <div class="py-attribute-table-column">
+ <span>_('Coroutines')</span>
+ <ul>
+ <li><a href="..."></li>
+ </ul>
+ </div>
+ <div class="py-attribute-table-column">
+ <span>_('Methods')</span>
+ <ul>
+ <li><a href="..."></li>
+ </ul>
+ </div>
+ ...
+ </div>
+
+ However, since this requires the tree to be complete
+ and parsed, it'll need to be done at a different stage and then
+ replaced.
+ """
+ content = self.arguments[0].strip()
+ node = attributetableplaceholder('')
+ modulename, name = self.parse_name(content)
+ node['python-module'] = modulename
+ node['python-class'] = name
+ node['python-full-name'] = '%s.%s' % (modulename, name)
+ return [node]
+
+def build_lookup_table(env):
+ # Given an environment, load up a lookup table of
+ # full-class-name: objects
+ result = {}
+ domain = env.domains['py']
+
+ ignored = {
+ 'data', 'exception', 'module', 'class',
+ }
+ for (fullname, (docname, objtype)) in domain.objects.items():
+ if objtype in ignored:
+ continue
+
+ classname, _, child = fullname.rpartition('.')
+ try:
+ result[classname].append(child)
+ except KeyError:
+ result[classname] = [child]
+
+ return result
+
+def process_attributetable(app, doctree, fromdocname):
+ env = app.builder.env
+
+ lookup = build_lookup_table(env)
+ for node in doctree.traverse(attributetableplaceholder):
+ modulename, classname, fullname = node['python-module'], node['python-class'], node['python-full-name']
+ groups = get_class_results(lookup, modulename, classname, fullname)
+ table = attributetable('')
+ for label, subitems in groups.items():
+ if not subitems:
+ continue
+ table.append(class_results_to_node(label, subitems))
+
+ table['python-class'] = fullname
+
+ if not table:
+ node.replace_self([])
+ else:
+ node.replace_self([table])
+
+def get_class_results(lookup, modulename, name, fullname):
+ module = importlib.import_module(modulename)
+ cls_dict = getattr(module, name).__dict__
+
+ groups = OrderedDict([
+ ('Attributes', []),
+ ('Coroutines', []),
+ ('Methods', []),
+ ('Decorators', []),
+ ])
+
+ try:
+ members = lookup[fullname]
+ except KeyError:
+ return groups
+
+ for attr in members:
+ attrlookup = '%s.%s' % (fullname, attr)
+ key = 'Attributes'
+ label = attr
+
+ value = cls_dict.get(attr)
+ if value is not None:
+ doc = value.__doc__ or ''
+ if inspect.iscoroutinefunction(value) or doc.startswith('|coro|'):
+ key = 'Coroutines'
+ elif inspect.isfunction(value):
+ if doc.startswith(('A decorator', 'A shortcut decorator')):
+ # finicky but surprisingly consistent
+ key = 'Decorators'
+ else:
+ key = 'Methods'
+
+ groups[key].append((attrlookup, label))
+
+ return groups
+
+def class_results_to_node(key, elements):
+ title = attributetabletitle(key, key)
+ ul = nodes.bullet_list('')
+ for fullname, label in elements:
+ ref = nodes.reference('', '', internal=True,
+ refuri='#' + fullname,
+ anchorname='',
+ *[nodes.Text(label)])
+ para = addnodes.compact_paragraph('', '', ref)
+ item = nodes.list_item('', para)
+ ul.append(item)
+
+ return attributetablecolumn('', title, ul)
+
+def setup(app):
+ app.add_directive('attributetable', PyAttributeTable)
+ app.add_node(attributetable, html=(visit_attributetable_node, depart_attributetable_node))
+ app.add_node(attributetablecolumn, html=(visit_attributetablecolumn_node, depart_attributetablecolumn_node))
+ app.add_node(attributetabletitle, html=(visit_attributetabletitle_node, depart_attributetabletitle_node))
+ app.add_node(attributetableplaceholder)
+ app.connect('doctree-resolved', process_attributetable)