python-trio / sphinxcontrib-trio Goto Github PK
View Code? Open in Web Editor NEWMake Sphinx better at documenting Python functions and methods
License: Other
Make Sphinx better at documenting Python functions and methods
License: Other
autodetect is confused by the async_friendly_context_manager
in trio_util and incorrectly detects :for:
on method multi_error_defer_to()
decorated by it.
I think you can drop these now;
"bysource"
should work now. (And if it doesn't I want to know ;-))
I just upgraded my sphinx and sphinxcontrib-trio (the latter to 1.0.2, which supposedly includes the fix?) and it still seems to enforce alphabetical ordering.
Originally posted by @oremanj in python-trio/trio#872 (comment)
Dependabot couldn't authenticate with https://pypi.python.org/simple/.
You can provide authentication details in your Dependabot dashboard by clicking into the account menu (in the top right) and selecting 'Config variables'.
Details and log:
https://bugs.gentoo.org/784152
# Sphinx version: 4.1.2
# Python version: 3.9.1 (CPython)
# Docutils version: 0.17.1 release
# Jinja2 version: 3.0.1
# Last messages:
# building [mo]: targets for 0 po files that are out of date
# building [html]: targets for 16 source files that are out of date
# updating environment:
# [new config]
# 16 added, 0 changed, 0 removed
# reading sources... [ 6%] api
# reading sources... [ 12%] index
# reading sources... [ 18%] installing
# reading sources... [ 25%] pincer
# reading sources... [ 31%] pincer.core
# Loaded extensions:
# sphinx.ext.mathjax (4.1.2) from C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinx\ext\mathjax.py
# sphinxcontrib.applehelp (1.0.2) from C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinxcontrib\applehelp\__init__.py
# sphinxcontrib.devhelp (1.0.2) from C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinxcontrib\devhelp\__init__.py
# sphinxcontrib.htmlhelp (2.0.0) from C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinxcontrib\htmlhelp\__init__.py
# sphinxcontrib.serializinghtml (1.1.5) from C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinxcontrib\serializinghtml\__init__.py
# sphinxcontrib.qthelp (1.0.3) from C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinxcontrib\qthelp\__init__.py
# alabaster (0.7.12) from C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\alabaster\__init__.py
# sphinx.ext.autodoc.preserve_defaults (1.0) from C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinx\ext\autodoc\preserve_defaults.py
# sphinx.ext.autodoc.type_comment (4.1.2) from C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinx\ext\autodoc\type_comment.py
# sphinx.ext.autodoc (4.1.2) from C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinx\ext\autodoc\__init__.py
# sphinx.ext.napoleon (4.1.2) from C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinx\ext\napoleon\__init__.py
# sphinx.ext.intersphinx (4.1.2) from C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinx\ext\intersphinx.py
# exception_hierarchy (unknown version) from C:\Users\olive\OneDrive\Documents\GitHub\Pincer-1\docs\extensions\exception_hierarchy.py
# attributetable (unknown version) from C:\Users\olive\OneDrive\Documents\GitHub\Pincer-1\docs\extensions\attributetable.py
# silence (unknown version) from C:\Users\olive\OneDrive\Documents\GitHub\Pincer-1\docs\extensions\silence.py
# sphinx_autodoc_typehints (unknown version) from C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinx_autodoc_typehints.py
# sphinxcontrib_trio (1.1.2) from C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinxcontrib_trio\__init__.py
# furo (2021.09.22) from C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\furo\__init__.py
Traceback (most recent call last):
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinx\cmd\build.py", line 280, in build_main
app.build(args.force_all, filenames)
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinx\application.py", line 343, in build
self.builder.build_update()
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinx\builders\__init__.py", line 293, in build_update
self.build(to_build,
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinx\builders\__init__.py", line 307, in build
updated_docnames = set(self.read())
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinx\builders\__init__.py", line 414, in read
self._read_serial(docnames)
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinx\builders\__init__.py", line 435, in _read_serial
self.read_doc(docname)
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinx\builders\__init__.py", line 475, in read_doc
doctree = read_doc(self.app, self.env, self.env.doc2path(docname))
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinx\io.py", line 188, in read_doc
pub.publish()
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\docutils\core.py", line 217, in publish
self.document = self.reader.read(self.source, self.parser,
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinx\io.py", line 108, in read
self.parse()
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\docutils\readers\__init__.py", line 78, in parse
self.parser.parse(self.input, document)
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinx\parsers.py", line 100, in parse
self.statemachine.run(inputlines, document, inliner=self.inliner)
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\docutils\parsers\rst\states.py", line 170, in run
results = StateMachineWS.run(self, input_lines, input_offset,
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\docutils\statemachine.py", line 239, in run
context, next_state, result = self.check_line(
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\docutils\statemachine.py", line 451, in check_line
return method(match, context, next_state)
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\docutils\parsers\rst\states.py", line 2769, in underline
self.section(title, source, style, lineno - 1, messages)
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\docutils\parsers\rst\states.py", line 327, in section
self.new_subsection(title, lineno, messages)
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\docutils\parsers\rst\states.py", line 393, in new_subsection
newabsoffset = self.nested_parse(
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\docutils\parsers\rst\states.py", line 281, in nested_parse
state_machine.run(block, input_offset, memo=self.memo,
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\docutils\parsers\rst\states.py", line 196, in run
results = StateMachineWS.run(self, input_lines, input_offset)
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\docutils\statemachine.py", line 239, in run
context, next_state, result = self.check_line(
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\docutils\statemachine.py", line 451, in check_line
return method(match, context, next_state)
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\docutils\parsers\rst\states.py", line 2769, in underline
self.section(title, source, style, lineno - 1, messages)
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\docutils\parsers\rst\states.py", line 327, in section
self.new_subsection(title, lineno, messages)
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\docutils\parsers\rst\states.py", line 393, in new_subsection
newabsoffset = self.nested_parse(
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\docutils\parsers\rst\states.py", line 281, in nested_parse
state_machine.run(block, input_offset, memo=self.memo,
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\docutils\parsers\rst\states.py", line 196, in run
results = StateMachineWS.run(self, input_lines, input_offset)
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\docutils\statemachine.py", line 239, in run
context, next_state, result = self.check_line(
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\docutils\statemachine.py", line 451, in check_line
return method(match, context, next_state)
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\docutils\parsers\rst\states.py", line 2342, in explicit_markup
nodelist, blank_finish = self.explicit_construct(match)
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\docutils\parsers\rst\states.py", line 2354, in explicit_construct
return method(self, expmatch)
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\docutils\parsers\rst\states.py", line 2096, in directive
return self.run_directive(
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\docutils\parsers\rst\states.py", line 2146, in run_directive
result = directive_instance.run()
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinx\ext\autodoc\directive.py", line 162, in run
documenter.generate(more_content=self.content)
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinx\ext\autodoc\__init__.py", line 979, in generate
self.document_members(all_members)
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinx\ext\autodoc\__init__.py", line 860, in document_members
documenter.generate(
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinx\ext\autodoc\__init__.py", line 1769, in generate
return super().generate(more_content=more_content,
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinx\ext\autodoc\__init__.py", line 979, in generate
self.document_members(all_members)
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinx\ext\autodoc\__init__.py", line 1760, in document_members
super().document_members(all_members)
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinx\ext\autodoc\__init__.py", line 860, in document_members
documenter.generate(
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinx\ext\autodoc\__init__.py", line 913, in generate
if not self.import_object():
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\site-packages\sphinxcontrib_trio\__init__.py", line 382, in import_object
obj = inspect.getattr_static(self.parent, self.object_name)
File "C:\Users\olive\AppData\Local\Programs\Python\Python39\lib\inspect.py", line 1648, in getattr_static
raise AttributeError(attr)
AttributeError: __dispatcher
I'm packaging your module as an rpm package so I'm using the typical PEP517 based build, install and test cycle used on building packages from non-root account.
python3 -sBm build -w --no-isolation
build
with --no-isolation
I'm using during all processes only locally installed modulescut off from access to the public network
(pytest is executed with -m "not network"
)+ PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-sphinxcontrib-trio-1.1.2-15.fc35.x86_64/usr/lib64/python3.8/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-sphinxcontrib-trio-1.1.2-15.fc35.x86_64/usr/lib/python3.8/site-packages
+ /usr/bin/pytest -ra -m 'not network'
==================================================================================== test session starts ====================================================================================
platform linux -- Python 3.8.18, pytest-7.4.4, pluggy-1.3.0
rootdir: /home/tkloczko/rpmbuild/BUILD/sphinxcontrib-trio-1.1.2
plugins: datadir-1.5.0, regressions-2.5.0
collected 3 items
tests/test_sphinxcontrib_trio.py .F. [100%]
========================================================================================= FAILURES ==========================================================================================
______________________________________________________________________________________ test_end_to_end ______________________________________________________________________________________
tmpdir = local('/tmp/pytest-of-tkloczko/pytest-69/test_end_to_end0')
def test_end_to_end(tmpdir):
shutil.copytree(str(Path(__file__).parent / "test-docs-source"),
str(tmpdir / "test-docs-source"))
subprocess.run(
["sphinx-build", "-v", "-nW", "-nb", "html",
str(tmpdir / "test-docs-source"), str(tmpdir / "out")])
tree = lxml.html.parse(str(tmpdir / "out" / "test.html")).getroot()
def do_html_test(node, *, expect_match):
original_content = node.text_content()
print("\n-- test case --\n", lxml.html.tostring(node, encoding="unicode"))
check_tags = node.cssselect(".highlight-none")
checks = []
for tag in check_tags:
text = tag.text_content().strip()
# lxml normalizes   to the unicode \xa0, so we do the same
text = text.replace(" ", "\xa0")
checks.append(text)
tag.drop_tree()
# make sure we removed the tests from the top-level node, to avoid
# potential false positives matching on the tests themselves!
assert len(node.text_content()) < len(original_content)
assert checks
test_content = lxml.html.tostring(node, encoding="unicode")
# some versions of sphinx (>= 1.6) replace "..." with the ellipsis
# character \u2026. Normalize back to "..." for comparison
# purposes.
test_content = test_content.replace("\u2026", "...")
for check in checks:
try:
if expect_match:
assert re.search(check, test_content) is not None
else:
assert re.search(check, test_content) is None
except AssertionError:
print("failed check")
print()
print(repr(check))
print()
print("failed test_content")
print()
print(repr(test_content))
raise
print("\n-- NEGATIVE (WARNING) TESTS --\n")
for warning in tree.cssselect(".warning"):
do_html_test(warning, expect_match=False)
print("\n-- POSITIVE (NOTE) TESTS --\n")
for note in tree.cssselect(".note"):
> do_html_test(note, expect_match=True)
tests/test_sphinxcontrib_trio.py:241:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
node = <Element div at 0x7f16e2bb8f90>
def do_html_test(node, *, expect_match):
original_content = node.text_content()
print("\n-- test case --\n", lxml.html.tostring(node, encoding="unicode"))
check_tags = node.cssselect(".highlight-none")
checks = []
for tag in check_tags:
text = tag.text_content().strip()
# lxml normalizes   to the unicode \xa0, so we do the same
text = text.replace(" ", "\xa0")
checks.append(text)
tag.drop_tree()
# make sure we removed the tests from the top-level node, to avoid
# potential false positives matching on the tests themselves!
assert len(node.text_content()) < len(original_content)
assert checks
test_content = lxml.html.tostring(node, encoding="unicode")
# some versions of sphinx (>= 1.6) replace "..." with the ellipsis
# character \u2026. Normalize back to "..." for comparison
# purposes.
test_content = test_content.replace("\u2026", "...")
for check in checks:
try:
if expect_match:
> assert re.search(check, test_content) is not None
E assert None is not None
E + where None = <function search at 0x7f16e4ed5430>('<em class="property">await </em><code class="(sig-name )?descname">foo</code>', '<div class="admonition note">\n<p class="admonition-title">Note</p>\n<dl class="py function">\n<dt class="sig sig-obj... class="n"><span class="pre">bar</span></span></em><span class="sig-paren">)</span></dt>\n<dd></dd></dl>\n\n\n</div>\n')
E + where <function search at 0x7f16e4ed5430> = re.search
tests/test_sphinxcontrib_trio.py:220: AssertionError
----------------------------------------------------------------------------------- Captured stdout call ------------------------------------------------------------------------------------
Running Sphinx v7.1.2
making output directory... done
locale_dir /tmp/pytest-of-tkloczko/pytest-69/test_end_to_end0/test-docs-source/locales/en/LC_MESSAGES does not exists
[autosummary] generating autosummary for: test.rst
[autosummary] generating autosummary for: /tmp/pytest-of-tkloczko/pytest-69/test_end_to_end0/test-docs-source/autodoc_examples.autosummary_me.rst
locale_dir /tmp/pytest-of-tkloczko/pytest-69/test_end_to_end0/test-docs-source/locales/en/LC_MESSAGES does not exists
building [mo]: targets for 0 po files that are out of date
writing output...
building [html]: targets for 1 source files that are out of date
updating environment: locale_dir /tmp/pytest-of-tkloczko/pytest-69/test_end_to_end0/test-docs-source/locales/en/LC_MESSAGES does not exists
[new config] 2 added, 0 changed, 0 removed
reading sources... [ 50%] autodoc_examples.autosummary_me
reading sources... [100%] test
looking for now-outdated files... none found
pickling environment... done
checking consistency... done
preparing documents... done
copying assets... copying static files... done
copying extra files... done
done
writing output... [ 50%] autodoc_examples.autosummary_me
writing output... [100%] test
generating indices... genindex py-modindex done
writing additional pages... search done
dumping search index in English (code: en)... done
dumping object inventory... done
build succeeded.
The HTML pages are in ../../../../../tmp/pytest-of-tkloczko/pytest-69/test_end_to_end0/out.
-- NEGATIVE (WARNING) TESTS --
-- test case --
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<dl class="py function">
<dt class="sig sig-object py">
<span class="sig-name descname"><span class="pre">foo</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">bar</span></span></em><span class="sig-paren">)</span></dt>
<dd></dd></dl>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span><em class="property">await </em><code class="(sig-name )?descname">foo</code>
</pre></div>
</div>
</div>
-- test case --
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<dl class="py function">
<dt class="sig sig-object py">
<span class="sig-prename descclassname"><span class="pre">autodoc_examples.</span></span><span class="sig-name descname"><span class="pre">basic</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd></dd></dl>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span></em><code class="(sig-name )?descname">basic</code>
</pre></div>
</div>
</div>
-- test case --
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<dl class="py class">
<dt class="sig sig-object py">
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">autodoc_examples.</span></span><span class="sig-name descname"><span class="pre">ExampleInheritedSubclass</span></span></dt>
<dd><dl class="py method">
<dt class="sig sig-object py">
<span class="sig-name descname"><span class="pre">a_syncmethod</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd></dd></dl>
<dl class="py method">
<dt class="sig sig-object py">
<span class="sig-name descname"><span class="pre">b_syncmethod</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd></dd></dl>
<dl class="py method">
<dt class="sig sig-object py">
<em class="property"><span class="pre">await</span> </em><span class="sig-name descname"><span class="pre">c_asyncmethod</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd></dd></dl>
<dl class="py method">
<dt class="sig sig-object py">
<em class="property"><span class="pre">await</span> </em><span class="sig-name descname"><span class="pre">d_asyncmethod</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd></dd></dl>
</dd></dl>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span><em class="property">await </em><code class="(sig-name )?descname">a_syncmethod</code>
</pre></div>
</div>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span><em class="property">await </em><code class="(sig-name )?descname">b_syncmethod</code>
</pre></div>
</div>
</div>
-- test case --
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<dl class="py function">
<dt class="sig sig-object py">
<span class="sig-prename descclassname"><span class="pre">autodoc_examples.</span></span><span class="sig-name descname"><span class="pre">gen</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd></dd></dl>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>for
</pre></div>
</div>
</div>
-- POSITIVE (NOTE) TESTS --
-- test case --
<div class="admonition note">
<p class="admonition-title">Note</p>
<dl class="py function">
<dt class="sig sig-object py">
<em class="property"><span class="pre">await</span> </em><span class="sig-name descname"><span class="pre">foo</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">bar</span></span></em><span class="sig-paren">)</span></dt>
<dd></dd></dl>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span><em class="property">await </em><code class="(sig-name )?descname">foo</code>
</pre></div>
</div>
</div>
failed check
'<em class="property">await </em><code class="(sig-name )?descname">foo</code>'
failed test_content
'<div class="admonition note">\n<p class="admonition-title">Note</p>\n<dl class="py function">\n<dt class="sig sig-object py">\n<em class="property"><span class="pre">await</span> </em><span class="sig-name descname"><span class="pre">foo</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">bar</span></span></em><span class="sig-paren">)</span></dt>\n<dd></dd></dl>\n\n\n</div>\n'
================================================================================== short test summary info ==================================================================================
FAILED tests/test_sphinxcontrib_trio.py::test_end_to_end - assert None is not None
================================================================================ 1 failed, 2 passed in 2.51s ================================================================================
Package Version
----------------------------- -------
alabaster 0.7.16
Babel 2.14.0
build 1.0.3
charset-normalizer 3.3.2
cppclean 0.13
cssselect 1.2.0
distro 1.9.0
dnf 4.18.2
docutils 0.20.1
exceptiongroup 1.1.3
gpg 1.23.2
idna 3.6
imagesize 1.4.1
importlib-metadata 7.0.1
iniconfig 2.0.0
installer 0.7.0
Jinja2 3.1.3
libdnf 0.72.0
lxml 5.0.0
MarkupSafe 2.1.3
packaging 23.2
pluggy 1.3.0
Pygments 2.17.2
pyproject_hooks 1.0.0
pytest 7.4.4
python-dateutil 2.8.2
pytz 2023.3
requests 2.31.0
setuptools 69.0.3
six 1.16.0
snowballstemmer 2.2.0
Sphinx 7.1.2
sphinxcontrib-applehelp 1.0.4
sphinxcontrib-devhelp 1.0.5
sphinxcontrib-htmlhelp 2.0.5
sphinxcontrib-jsmath 1.0.1
sphinxcontrib-qthelp 1.0.7
sphinxcontrib-serializinghtml 1.1.10
tomli 2.0.1
urllib3 1.26.18
wheel 0.42.0
zipp 3.17.0
Please let me know if you need more details or want me to perform some diagnostics.
@thmo reported this crash when building the pytest docs (apparently they use sphinxcontrib-trio now, I had no idea :-)):
# Sphinx version: 1.7.5
# Python version: 3.6.6 (CPython)
# Docutils version: 0.14
# Jinja2 version: 2.10
# Last messages:
# reading sources... [ 89%] projects
#
# reading sources... [ 90%] proposals/parametrize_with_fixtures
#
# reading sources... [ 91%] pythonpath
#
# reading sources... [ 92%] recwarn
#
# reading sources... [ 92%] reference
#
# Loaded extensions:
# alabaster (0.7.9) from /usr/lib/python3.6/site-packages/alabaster/__init__.py
# sphinx.ext.autodoc (1.7.5) from /usr/lib/python3.6/site-packages/sphinx/ext/autodoc/__init__.py
# sphinx.ext.todo (1.7.5) from /usr/lib/python3.6/site-packages/sphinx/ext/todo.py
# sphinx.ext.autosummary (1.7.5) from /usr/lib/python3.6/site-packages/sphinx/ext/autosummary/__init__.py
# sphinx.ext.intersphinx (1.7.5) from /usr/lib/python3.6/site-packages/sphinx/ext/intersphinx.py
# sphinx.ext.viewcode (1.7.5) from /usr/lib/python3.6/site-packages/sphinx/ext/viewcode.py
# sphinxcontrib_trio (1.0.1) from /usr/lib/python3.6/site-packages/sphinxcontrib_trio/__init__.py
Traceback (most recent call last):
File "/usr/lib/python3.6/site-packages/sphinx/cmdline.py", line 304, in main
app.build(args.force_all, filenames)
File "/usr/lib/python3.6/site-packages/sphinx/application.py", line 331, in build
self.builder.build_update()
File "/usr/lib/python3.6/site-packages/sphinx/builders/__init__.py", line 342, in build_update
'out of date' % len(to_build))
File "/usr/lib/python3.6/site-packages/sphinx/builders/__init__.py", line 355, in build
updated_docnames = set(self.env.update(self.config, self.srcdir, self.doctreedir))
File "/usr/lib/python3.6/site-packages/sphinx/environment/__init__.py", line 565, in update
self._read_serial(docnames, self.app)
File "/usr/lib/python3.6/site-packages/sphinx/environment/__init__.py", line 584, in _read_serial
self.read_doc(docname, app)
File "/usr/lib/python3.6/site-packages/sphinx/environment/__init__.py", line 659, in read_doc
doctree = read_doc(self.app, self, self.doc2path(docname))
File "/usr/lib/python3.6/site-packages/sphinx/io.py", line 294, in read_doc
pub.publish()
File "/usr/lib/python3.6/site-packages/docutils/core.py", line 217, in publish
self.settings)
File "/usr/lib/python3.6/site-packages/docutils/readers/__init__.py", line 72, in read
self.parse()
File "/usr/lib/python3.6/site-packages/docutils/readers/__init__.py", line 78, in parse
self.parser.parse(self.input, document)
File "/usr/lib/python3.6/site-packages/sphinx/parsers.py", line 85, in parse
self.statemachine.run(inputstring, document, inliner=self.inliner)
File "/usr/lib/python3.6/site-packages/docutils/parsers/rst/states.py", line 171, in run
input_source=document['source'])
File "/usr/lib/python3.6/site-packages/docutils/statemachine.py", line 239, in run
context, state, transitions)
File "/usr/lib/python3.6/site-packages/docutils/statemachine.py", line 460, in check_line
return method(match, context, next_state)
File "/usr/lib/python3.6/site-packages/docutils/parsers/rst/states.py", line 2753, in underline
self.section(title, source, style, lineno - 1, messages)
File "/usr/lib/python3.6/site-packages/docutils/parsers/rst/states.py", line 327, in section
self.new_subsection(title, lineno, messages)
File "/usr/lib/python3.6/site-packages/docutils/parsers/rst/states.py", line 395, in new_subsection
node=section_node, match_titles=True)
File "/usr/lib/python3.6/site-packages/docutils/parsers/rst/states.py", line 282, in nested_parse
node=node, match_titles=match_titles)
File "/usr/lib/python3.6/site-packages/docutils/parsers/rst/states.py", line 196, in run
results = StateMachineWS.run(self, input_lines, input_offset)
File "/usr/lib/python3.6/site-packages/docutils/statemachine.py", line 239, in run
context, state, transitions)
File "/usr/lib/python3.6/site-packages/docutils/statemachine.py", line 460, in check_line
return method(match, context, next_state)
File "/usr/lib/python3.6/site-packages/docutils/parsers/rst/states.py", line 2753, in underline
self.section(title, source, style, lineno - 1, messages)
File "/usr/lib/python3.6/site-packages/docutils/parsers/rst/states.py", line 327, in section
self.new_subsection(title, lineno, messages)
File "/usr/lib/python3.6/site-packages/docutils/parsers/rst/states.py", line 395, in new_subsection
node=section_node, match_titles=True)
File "/usr/lib/python3.6/site-packages/docutils/parsers/rst/states.py", line 282, in nested_parse
node=node, match_titles=match_titles)
File "/usr/lib/python3.6/site-packages/docutils/parsers/rst/states.py", line 196, in run
results = StateMachineWS.run(self, input_lines, input_offset)
File "/usr/lib/python3.6/site-packages/docutils/statemachine.py", line 239, in run
context, state, transitions)
File "/usr/lib/python3.6/site-packages/docutils/statemachine.py", line 460, in check_line
return method(match, context, next_state)
File "/usr/lib/python3.6/site-packages/docutils/parsers/rst/states.py", line 2753, in underline
self.section(title, source, style, lineno - 1, messages)
File "/usr/lib/python3.6/site-packages/docutils/parsers/rst/states.py", line 327, in section
self.new_subsection(title, lineno, messages)
File "/usr/lib/python3.6/site-packages/docutils/parsers/rst/states.py", line 395, in new_subsection
node=section_node, match_titles=True)
File "/usr/lib/python3.6/site-packages/docutils/parsers/rst/states.py", line 282, in nested_parse
node=node, match_titles=match_titles)
File "/usr/lib/python3.6/site-packages/docutils/parsers/rst/states.py", line 196, in run
results = StateMachineWS.run(self, input_lines, input_offset)
File "/usr/lib/python3.6/site-packages/docutils/statemachine.py", line 239, in run
context, state, transitions)
File "/usr/lib/python3.6/site-packages/docutils/statemachine.py", line 460, in check_line
return method(match, context, next_state)
File "/usr/lib/python3.6/site-packages/docutils/parsers/rst/states.py", line 2326, in explicit_markup
nodelist, blank_finish = self.explicit_construct(match)
File "/usr/lib/python3.6/site-packages/docutils/parsers/rst/states.py", line 2338, in explicit_construct
return method(self, expmatch)
File "/usr/lib/python3.6/site-packages/docutils/parsers/rst/states.py", line 2081, in directive
directive_class, match, type_name, option_presets)
File "/usr/lib/python3.6/site-packages/docutils/parsers/rst/states.py", line 2130, in run_directive
result = directive_instance.run()
File "/usr/lib/python3.6/site-packages/sphinx/ext/autodoc/directive.py", line 133, in run
documenter.generate(more_content=self.content)
File "/usr/lib/python3.6/site-packages/sphinx/ext/autodoc/__init__.py", line 747, in generate
if not self.import_object():
File "/usr/lib/python3.6/site-packages/sphinxcontrib_trio/__init__.py", line 350, in import_object
obj = self.parent.__dict__.get(self.object_name)
AttributeError: 'NoneType' object has no attribute '__dict__'
From a quick skim, I think the issue is that somehow autodoc was trying to look up an unknown method (e.g. .. automethod:: SomeClass.misspelled_nmae
), and we're crashing instead of reporting a proper error message.
Specifically, it looks like we need to port this fix: sphinx-doc/sphinx@1d742bd into sphinxcontrib-trio's version of MethodDocumentor.import_object
Well, I'm not entirely sure whether that's the actual issue because I'm not sure what exactly @thmo was doing or how to reproduce it, but this seems like a good idea regardless :-)
Dependabot can't resolve your Python dependency files.
As a result, Dependabot couldn't update your dependencies.
The error Dependabot encountered was:
Could not find a version that satisfies the requirement pyparsing==2.4.1 (from packaging==19.0->pytest==5.0.1->-r test-requirements.in (line 1)) (from versions: 1.4.6, 1.4.7, 1.4.8, 1.4.11, 1.5.0, 1.5.1, 1.5.2, 1.5.3, 1.5.4, 1.5.5, 1.5.6, 1.5.7, 2.0.0, 2.0.1, 2.0.2, 2.0.3, 2.0.4, 2.0.5, 2.0.6, 2.0.7, 2.1.0, 2.1.1, 2.1.2, 2.1.3, 2.1.4, 2.1.5, 2.1.6, 2.1.7, 2.1.8, 2.1.9, 2.1.10, 2.2.0, 2.2.1, 2.2.2, 2.3.0, 2.3.1, 2.4.0)
Traceback (most recent call last):
File "/usr/local/.pyenv/versions/3.7.3/bin/pip-compile", line 10, in <module>
sys.exit(cli())
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/click/core.py", line 764, in __call__
return self.main(*args, **kwargs)
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/click/core.py", line 717, in main
rv = self.invoke(ctx)
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/click/core.py", line 956, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/click/core.py", line 555, in invoke
return callback(*args, **kwargs)
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/click/decorators.py", line 17, in new_func
return f(get_current_context(), *args, **kwargs)
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/piptools/scripts/compile.py", line 350, in cli
results = resolver.resolve(max_rounds=max_rounds)
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/piptools/resolver.py", line 164, in resolve
has_changed, best_matches = self._resolve_one_round()
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/piptools/resolver.py", line 259, in _resolve_one_round
their_constraints.extend(self._iter_dependencies(best_match))
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/piptools/resolver.py", line 354, in _iter_dependencies
dependencies = self.repository.get_dependencies(ireq)
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/piptools/repositories/local.py", line 66, in get_dependencies
return self.repository.get_dependencies(ireq)
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/piptools/repositories/pypi.py", line 270, in get_dependencies
download_dir, ireq, wheel_cache
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/piptools/repositories/pypi.py", line 229, in resolve_reqs
results = resolver._resolve_one(reqset, ireq)
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/pip/_internal/resolve.py", line 294, in _resolve_one
abstract_dist = self._get_abstract_dist_for(req_to_install)
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/pip/_internal/resolve.py", line 242, in _get_abstract_dist_for
self.require_hashes
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/pip/_internal/operations/prepare.py", line 282, in prepare_linked_requirement
req.populate_link(finder, upgrade_allowed, require_hashes)
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/pip/_internal/req/req_install.py", line 198, in populate_link
self.link = finder.find_requirement(self, upgrade)
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/pip/_internal/index.py", line 792, in find_requirement
'No matching distribution found for %s' % req
pip._internal.exceptions.DistributionNotFound: No matching distribution found for pyparsing==2.4.1 (from packaging==19.0->pytest==5.0.1->-r test-requirements.in (line 1))
If you think the above is an error on Dependabot's side please don't hesitate to get in touch - we'll do whatever we can to fix it.
You can mention @dependabot in the comments below to contact the Dependabot team.
It's harshing our stats
I tried to autofunction
this function:
QueueItem = Union[asyncio.Future, str]
# the expansion of `Optional` makes me realize that `wait: bool=False` is probably more correct
async def pump_queue(queue: Deque[QueueItem], wait: Optional[bool]=False) -> AsyncGenerator[str, None]:
"""
foo
Args:
queue (Deque[QueueItem]):
wait (Optional[bool]):
Returns:
AsyncGenerator[str, None]:
"""
Result:
There are a few problems with this:
QueueItem
isn't expanded like it is in the function definition)Returns: AsyncGenerator[…]
is probably more accurate than saying this yields
, but I'm not sure.Do you have any ideas on how/if return types should be reconciled with the implied return types from the await
and async for …
prefixes that sphinxcontrib-trio adds?
Is PEP484 and/or modifying docstring parsing behavior in-scope for this extension at all?
https://www.sphinx-doc.org/en/master/extdev/deprecated.html
venv/lib/site-packages/sphinx/domains/python.py:659:
RemovedInSphinx40Warning: PyClassmember is deprecated. Please check the implementation of <class 'sphinxcontrib_trio.ExtendedPyMethod'>
Dependabot can't resolve your Python dependency files.
As a result, Dependabot couldn't update your dependencies.
The error Dependabot encountered was:
Could not find a version that satisfies the requirement pyparsing==2.4.1 (from packaging==19.0->pytest==5.0.1->-r test-requirements.in (line 1)) (from versions: 1.4.6, 1.4.7, 1.4.8, 1.4.11, 1.5.0, 1.5.1, 1.5.2, 1.5.3, 1.5.4, 1.5.5, 1.5.6, 1.5.7, 2.0.0, 2.0.1, 2.0.2, 2.0.3, 2.0.4, 2.0.5, 2.0.6, 2.0.7, 2.1.0, 2.1.1, 2.1.2, 2.1.3, 2.1.4, 2.1.5, 2.1.6, 2.1.7, 2.1.8, 2.1.9, 2.1.10, 2.2.0, 2.2.1, 2.2.2, 2.3.0, 2.3.1, 2.4.0, 2.4.1.1, 2.4.2a1)
Traceback (most recent call last):
File "/usr/local/.pyenv/versions/3.7.3/bin/pip-compile", line 10, in <module>
sys.exit(cli())
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/click/core.py", line 764, in __call__
return self.main(*args, **kwargs)
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/click/core.py", line 717, in main
rv = self.invoke(ctx)
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/click/core.py", line 956, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/click/core.py", line 555, in invoke
return callback(*args, **kwargs)
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/click/decorators.py", line 17, in new_func
return f(get_current_context(), *args, **kwargs)
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/piptools/scripts/compile.py", line 350, in cli
results = resolver.resolve(max_rounds=max_rounds)
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/piptools/resolver.py", line 164, in resolve
has_changed, best_matches = self._resolve_one_round()
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/piptools/resolver.py", line 259, in _resolve_one_round
their_constraints.extend(self._iter_dependencies(best_match))
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/piptools/resolver.py", line 354, in _iter_dependencies
dependencies = self.repository.get_dependencies(ireq)
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/piptools/repositories/local.py", line 66, in get_dependencies
return self.repository.get_dependencies(ireq)
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/piptools/repositories/pypi.py", line 270, in get_dependencies
download_dir, ireq, wheel_cache
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/piptools/repositories/pypi.py", line 229, in resolve_reqs
results = resolver._resolve_one(reqset, ireq)
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/pip/_internal/resolve.py", line 294, in _resolve_one
abstract_dist = self._get_abstract_dist_for(req_to_install)
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/pip/_internal/resolve.py", line 242, in _get_abstract_dist_for
self.require_hashes
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/pip/_internal/operations/prepare.py", line 282, in prepare_linked_requirement
req.populate_link(finder, upgrade_allowed, require_hashes)
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/pip/_internal/req/req_install.py", line 198, in populate_link
self.link = finder.find_requirement(self, upgrade)
File "/usr/local/.pyenv/versions/3.7.3/lib/python3.7/site-packages/pip/_internal/index.py", line 792, in find_requirement
'No matching distribution found for %s' % req
pip._internal.exceptions.DistributionNotFound: No matching distribution found for pyparsing==2.4.1 (from packaging==19.0->pytest==5.0.1->-r test-requirements.in (line 1))
If you think the above is an error on Dependabot's side please don't hesitate to get in touch - we'll do whatever we can to fix it.
You can mention @dependabot in the comments below to contact the Dependabot team.
(curious-yiBjxk2Q) $ make html
Running Sphinx v1.7.0b2
Extension error:
Could not import extension sphinxcontrib_trio (exception: cannot import name 'Options' from 'sphinx.ext.autodoc' (/home/laura/.local/share/virtualenvs/curious-yiBjxk2Q/lib/python3.7/site-packages/sphinx/ext/autodoc/__init__.py))
make: *** [Makefile:20: html] Error 2
Options seems to have been removed from sphinx.ext.autodoc (but it's not in the changelog?)
When using autodoc to document a class that inherits an async method from its base class, the inherited method is not detected as async.
Basically, with code like this:
class SomeBaseClass:
"""The base class."""
async def base_async_method(self):
"""This is an async method in the base class."""
pass
class SomeDerivedClass(SomeBaseClass):
"""The derived class."""
async def derived_async_method(self):
"""This is an async method in the derived class."""
pass
and autodoc directives like this:
.. automodule:: some_async_module
:members:
:inherited-members:
The output documentation is like this:
class some_async_module.SomeBaseClass
The base class. await base_async_method() This is an async method in the base class.
class some_async_module.SomeDerivedClass
The derived class. base_async_method() This is an async method in the base class. await derived_async_method() This is an async method in the derived class.
Similarly to how :meta private:
, :meta public:
, or :meta hide-value:
in Sphinx work (see the docs here), I would want to be able to mark function as a decorator/abstractmethod/etc using something like this:
def function():
"""
Description of the method
:trio decorator:
:trio classmethod:
"""
It should probably be possible to base its implementation on Sphinx's own implementation used for the :meta:
fields.
+ /usr/bin/python3 setup.py build_sphinx -b man --build-dir build/sphinx
running build_sphinx
Running Sphinx v4.0.2
making output directory... done
Exception occurred:
File "/home/tkloczko/rpmbuild/BUILD/sphinxcontrib-trio-1.1.2/docs/source/conf.py", line 41, in setup
app.add_stylesheet("hack.css")
AttributeError: 'Sphinx' object has no attribute 'add_stylesheet'
The full traceback has been saved in /tmp/sphinx-err-tzixrvcy.log, if you want to report the issue to the developers.
Please also report this if it was a user error, so that a better error message can be provided next time.
A bug report can be filed in the tracker at <https://github.com/sphinx-doc/sphinx/issues>. Thanks!
[tkloczko@barrel SPECS]$ cat /tmp/sphinx-err-tzixrvcy.log
# Sphinx version: 4.0.2
# Python version: 3.8.9 (CPython)
# Docutils version: 0.16 release
# Jinja2 version: 3.0.1
# Last messages:
# Loaded extensions:
Traceback (most recent call last):
File "/usr/lib/python3.8/site-packages/sphinx/setup_command.py", line 169, in run
app = Sphinx(self.source_dir, self.config_dir,
File "/usr/lib/python3.8/site-packages/sphinx/application.py", line 257, in __init__
self.config.setup(self)
File "/home/tkloczko/rpmbuild/BUILD/sphinxcontrib-trio-1.1.2/docs/source/conf.py", line 41, in setup
app.add_stylesheet("hack.css")
AttributeError: 'Sphinx' object has no attribute 'add_stylesheet'
Using the autosummary module, sphinxcontrib-trio fails to pick up markers on my functions.
This differs from regular autodoc, where it does - autosummary is probably doing something that isn't hooked properly?
The next version of sphinx is adding :async:
, :staticmethod:
, :classmethod:
attributes for functions and methods, along with autodoc support: sphinx-doc/sphinx#6295
This is great, but will almost certainly conflict with this plugin :-).
A few differences I noticed:
When a method is marked :async:
, they add the word "async" to the signature. We add "await". I think "await" is better, because (a) people read docs to learn how to use things, (b) showing how to use it is more consistent with how we show generators, context managers, decorators, etc.. E.g. if you have an async function that returns an async generator, we show the signature like async for ... in await somefunc(...)
, while if we follow sphinx then it would be async for ... in async somefunc(...)
, which is just confusing. OTOH whatever sphinx does by default might become the standard, and if people are used to seeing it one way then it'll be confusing if we do it a different way.
When a method is marked :staticmethod:
, they add the word "static" to the signature, instead of "staticmethod". Kinda odd but whatever.
I think their autodoc sniffing is currently broken when you combine multiple features together, e.g. it will give the wrong results if you have an async classmethod. sphinxcontrib-trio needed a ton of hacks to get the details right. And our test suite for these features is wayyy more thorough than sphinx's. They seem to be reinventing all this from scratch, so they're having to rediscover all this...
CC: @tk0miya
Hello,
I am trying to get sphinx to handle async methods in my project. I had good results with sphinxcontrib-trio
so far, but I cannot achieve the member ordering I want.
My sphinx configuration has autodoc_member_order = 'bysource'
defined.
The directive seems not to be applied to asynchronous functions. I end up with class members ordered this way:
Expected result:
All members together, in source order.
Help most welcome.
@Fuyukai reports running into a strange crash: https://gitter.im/python-trio/general?at=5b6730c63a5a2d2f99f91e22
This seems to be an incompatibility between #14 and whatever version of sphinx she's using (which it sounds like is some kind of 1.6.x, though I haven't confirmed this).
When we merged #14, we thought that it worked with any sphinx 1.6.x or 1.7.x. First problem is, we didn't actually add a >= 1.6
to this package's install_requires
in setup.py
, whoops.
Second problem: I'm not sure that >= 1.6
is the right thing! @Fuyukai's problem seems to be with a 1.6.x release, and I just checked the latest 1.6.x release tag, and it doesn't have a sphinx.pycode.parser
module: https://github.com/sphinx-doc/sphinx/tree/v1.6.7/sphinx/pycode
But somehow our CI tests are passing on 1.6, but weren't on 1.5? Something weird is going on here.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.