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

Initial work on Ice for Python API reference documentation #2535

Merged
merged 16 commits into from
Jul 25, 2024
16 changes: 16 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ jobs:
- name: Install doxygen and graphviz (a dependency of Doxygen for generating diagrams)
run: brew install doxygen graphviz || true

- name: Install virtualenv for Python docs
run: pipx install virtualenv

- name: Build C++
working-directory: ./cpp
run: make V=1 srcs
Expand All @@ -48,6 +51,17 @@ jobs:
run: |
make doc

- name: Generate Python Documentation
working-directory: ./python/docs
run: |
make -C ../../cpp slice2py Ice IceDiscovery IceLocatorDiscovery
make -C ../
virtualenv .venv
source .venv/bin/activate
pip install -r requirements.txt
make html
deactivate

- name: Generate Documentation for Swift
run: |
mkdir ./swift/docs
Expand All @@ -72,6 +86,8 @@ jobs:

aws s3 sync ./js/docs s3://${AWS_S3_DOC_BUCKET}/api/ice/main/js --delete

aws s3 sync ./python/docs/_build/html s3://${AWS_S3_DOC_BUCKET}/api/ice/main/python --delete

for target in Ice Glacier2 IceGrid IceStorm; do
aws s3 sync ./swift/docs/$target s3://${AWS_S3_DOC_BUCKET}/api/ice/main/swift/$target --delete
done
Expand Down
150 changes: 75 additions & 75 deletions cpp/src/slice2py/PythonUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,58 +408,58 @@ Slice::Python::CodeVisitor::visitInterfaceDecl(const InterfaceDeclPtr& p)
void
Slice::Python::CodeVisitor::writeOperations(const InterfaceDefPtr& p)
{
OperationList ops = p->operations();
if (!ops.empty())
OperationList operations = p->operations();
//
// Emit a placeholder for each operation.
//
for (const auto& operation : operations)
{
//
// Emit a placeholder for each operation.
//
for (OperationList::iterator oli = ops.begin(); oli != ops.end(); ++oli)
{
string fixedOpName = fixIdent((*oli)->name());

if ((*oli)->hasMarshaledResult())
{
string name = (*oli)->name();
name[0] = static_cast<char>(toupper(static_cast<unsigned char>(name[0])));
_out << sp;
_out << nl << "\"\"\"";
_out << nl << "Immediately marshals the result of an invocation of " << (*oli)->name() << nl
<< "and returns an object that the servant implementation must return" << nl << "as its result."
<< nl << "Arguments:" << nl << "result -- The result (or result tuple) of the invocation." << nl
<< "current -- The Current object passed to the invocation." << nl
<< "Returns: An object containing the marshaled result.";
_out << nl << "\"\"\"";
_out << nl << "@staticmethod";
_out << nl << "def " << name << "MarshaledResult(result, current):";
_out.inc();
_out << nl << "return IcePy.MarshaledResult(result, _M_" << getAbsolute(p) << "._op_" << (*oli)->name()
<< ", current.adapter.getCommunicator()._getImpl(), current.encoding)";
_out.dec();
}
string fixedOpName = fixIdent(operation->name());

_out << sp << nl << "def " << fixedOpName << "(self";
if (operation->hasMarshaledResult())
{
string name = operation->name();
name[0] = static_cast<char>(toupper(static_cast<unsigned char>(name[0])));
_out << sp;
_out << nl << "@staticmethod";
_out << nl << "def " << name << "MarshaledResult(result, current):";
_out.inc();
_out << nl << tripleQuotes;
_out << nl << "Immediately marshals the result of an invocation of " << name;
_out << nl << "and returns an object that the servant implementation must return";
_out << nl << "as its result.";
_out << nl;
_out << nl << "Args:";
_out << nl << " result: The result (or result tuple) of the invocation.";
_out << nl << " current: The Current object passed to the invocation.";
_out << nl;
_out << nl << "Returns";
_out << nl << " An object containing the marshaled result.";
_out << nl << tripleQuotes;
_out << nl << "return IcePy.MarshaledResult(result, _M_" << getAbsolute(p) << "._op_" << fixedOpName
<< ", current.adapter.getCommunicator()._getImpl(), current.encoding)";
_out.dec();
}

ParamDeclList params = (*oli)->parameters();
_out << sp << nl << "def " << fixedOpName << "(self";

for (ParamDeclList::iterator pli = params.begin(); pli != params.end(); ++pli)
for (const auto& param : operation->parameters())
{
if (!param->isOutParam())
{
if (!(*pli)->isOutParam())
{
_out << ", " << fixIdent((*pli)->name());
}
_out << ", " << fixIdent(param->name());
}
}

const string currentParamName = getEscapedParamName(*oli, "current");
_out << ", " << currentParamName << "=None";
_out << "):";
_out.inc();
const string currentParamName = getEscapedParamName(operation, "current");
_out << ", " << currentParamName << "=None";
_out << "):";
_out.inc();

writeDocstring(*oli, DocAsyncDispatch);
writeDocstring(operation, DocAsyncDispatch);

_out << nl << "raise NotImplementedError(\"servant method '" << fixedOpName << "' not implemented\")";
_out.dec();
}
_out << nl << "raise NotImplementedError(\"servant method '" << fixedOpName << "' not implemented\")";
_out.dec();
}
}

Expand Down Expand Up @@ -704,16 +704,16 @@ Slice::Python::CodeVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p)
_out << nl << "super().__init__(communicator, proxyString)";
_out.dec();

OperationList ops = p->operations();
for (OperationList::iterator oli = ops.begin(); oli != ops.end(); ++oli)
OperationList operations = p->operations();
for (const auto& operation : operations)
{
string fixedOpName = fixIdent((*oli)->name());
string fixedOpName = fixIdent(operation->name());
if (fixedOpName == "checkedCast" || fixedOpName == "uncheckedCast")
{
fixedOpName.insert(0, "_");
}
TypePtr ret = (*oli)->returnType();
ParamDeclList paramList = (*oli)->parameters();
TypePtr ret = operation->returnType();
ParamDeclList paramList = operation->parameters();
string inParams;
string inParamsDecl;

Expand Down Expand Up @@ -754,16 +754,16 @@ Slice::Python::CodeVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p)
}

_out << sp;
writeDocstring(*oli, DocSync);
_out << nl << "def " << fixedOpName << "(self";
if (!inParamsDecl.empty())
{
_out << ", " << inParamsDecl;
}
const string contextParamName = getEscapedParamName(*oli, "context");
const string contextParamName = getEscapedParamName(operation, "context");
_out << ", " << contextParamName << "=None):";
_out.inc();
_out << nl << "return _M_" << classAbs << "._op_" << (*oli)->name() << ".invoke(self, ((" << inParams;
writeDocstring(operation, DocSync);
_out << nl << "return _M_" << classAbs << "._op_" << operation->name() << ".invoke(self, ((" << inParams;
if (!inParams.empty() && inParams.find(',') == string::npos)
{
_out << ", ";
Expand All @@ -775,15 +775,15 @@ Slice::Python::CodeVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p)
// Async operations.
//
_out << sp;
writeDocstring(*oli, DocAsync);
_out << nl << "def " << (*oli)->name() << "Async(self";
_out << nl << "def " << operation->name() << "Async(self";
if (!inParams.empty())
{
_out << ", " << inParams;
}
_out << ", " << contextParamName << "=None):";
_out.inc();
_out << nl << "return _M_" << classAbs << "._op_" << (*oli)->name() << ".invokeAsync(self, ((" << inParams;
writeDocstring(operation, DocAsync);
_out << nl << "return _M_" << classAbs << "._op_" << operation->name() << ".invokeAsync(self, ((" << inParams;
if (!inParams.empty() && inParams.find(',') == string::npos)
{
_out << ", ";
Expand Down Expand Up @@ -929,17 +929,17 @@ Slice::Python::CodeVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p)
// where InParams and OutParams are tuples of type descriptions, and Exceptions
// is a tuple of exception type ids.
//
if (!ops.empty())
if (!operations.empty())
{
_out << sp;
}
for (OperationList::iterator s = ops.begin(); s != ops.end(); ++s)
for (const auto& operation : operations)
{
ParamDeclList params = (*s)->parameters();
ParamDeclList params = operation->parameters();
ParamDeclList::iterator t;
int count;
string format;
switch ((*s)->format())
switch (operation->format())
{
case DefaultFormat:
format = "None";
Expand All @@ -952,10 +952,10 @@ Slice::Python::CodeVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p)
break;
}

_out << nl << className << "._op_" << (*s)->name() << " = IcePy.Operation('" << (*s)->name() << "', "
<< getOperationMode((*s)->mode()) << ", "
<< ((p->hasMetaData("amd") || (*s)->hasMetaData("amd")) ? "True" : "False") << ", " << format << ", ";
writeMetaData((*s)->getMetaData());
_out << nl << className << "._op_" << operation->name() << " = IcePy.Operation('" << operation->name() << "', "
<< getOperationMode(operation->mode()) << ", "
<< ((p->hasMetaData("amd") || operation->hasMetaData("amd")) ? "True" : "False") << ", " << format << ", ";
writeMetaData(operation->getMetaData());
_out << ", (";
for (t = params.begin(), count = 0; t != params.end(); ++t)
{
Expand Down Expand Up @@ -1001,7 +1001,7 @@ Slice::Python::CodeVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p)
_out << ',';
}
_out << "), ";
TypePtr returnType = (*s)->returnType();
TypePtr returnType = operation->returnType();
if (returnType)
{
//
Expand All @@ -1011,15 +1011,15 @@ Slice::Python::CodeVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p)
//
_out << "((), ";
writeType(returnType);
_out << ", " << ((*s)->returnIsOptional() ? "True" : "False") << ", "
<< ((*s)->returnIsOptional() ? (*s)->returnTag() : 0) << ')';
_out << ", " << (operation->returnIsOptional() ? "True" : "False") << ", "
<< (operation->returnIsOptional() ? operation->returnTag() : 0) << ')';
}
else
{
_out << "None";
}
_out << ", (";
ExceptionList exceptions = (*s)->throws();
ExceptionList exceptions = operation->throws();
for (ExceptionList::iterator u = exceptions.begin(); u != exceptions.end(); ++u)
{
if (u != exceptions.begin())
Expand All @@ -1034,11 +1034,11 @@ Slice::Python::CodeVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p)
}
_out << "))";

if ((*s)->isDeprecated(true))
if (operation->isDeprecated(true))
{
// Get the deprecation reason if present, or default to an empty string.
string reason = (*s)->getDeprecationReason(true).value_or("");
_out << nl << className << "._op_" << (*s)->name() << ".deprecate(\"" << reason << "\")";
string reason = operation->getDeprecationReason(true).value_or("");
_out << nl << className << "._op_" << operation->name() << ".deprecate(\"" << reason << "\")";
}
}

Expand Down Expand Up @@ -2142,14 +2142,14 @@ Slice::Python::CodeVisitor::writeDocstring(const string& comment, const string&
return;
}

_out << nl << prefix << "\"\"\"";
_out << nl << prefix << tripleQuotes;

for (StringVec::const_iterator q = lines.begin(); q != lines.end(); ++q)
{
_out << nl << *q;
}

_out << nl << "\"\"\"";
_out << nl << tripleQuotes;
}

void
Expand All @@ -2161,7 +2161,7 @@ Slice::Python::CodeVisitor::writeDocstring(const string& comment, const DataMemb
return;
}

_out << nl << "\"\"\"";
_out << nl << tripleQuotes;

for (StringVec::const_iterator q = lines.begin(); q != lines.end(); ++q)
{
Expand Down Expand Up @@ -2207,7 +2207,7 @@ Slice::Python::CodeVisitor::writeDocstring(const string& comment, const DataMemb
}
}

_out << nl << "\"\"\"";
_out << nl << tripleQuotes;
}

void
Expand All @@ -2219,7 +2219,7 @@ Slice::Python::CodeVisitor::writeDocstring(const string& comment, const Enumerat
return;
}

_out << nl << "\"\"\"";
_out << nl << tripleQuotes;

for (StringVec::const_iterator q = lines.begin(); q != lines.end(); ++q)
{
Expand Down Expand Up @@ -2265,7 +2265,7 @@ Slice::Python::CodeVisitor::writeDocstring(const string& comment, const Enumerat
}
}

_out << nl << "\"\"\"";
_out << nl << tripleQuotes;
}

bool
Expand Down
2 changes: 2 additions & 0 deletions python/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
dist
docs/_build
docs/.venv
10 changes: 10 additions & 0 deletions python/docs/Ice.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Ice package
===========

Module contents
---------------

.. automodule:: Ice
:members:
:undoc-members:
:show-inheritance:
10 changes: 10 additions & 0 deletions python/docs/IceMX.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
IceMX package
=============

Module contents
---------------

.. automodule:: IceMX
:members:
:undoc-members:
:show-inheritance:
20 changes: 20 additions & 0 deletions python/docs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
Copy link
Member Author

Choose a reason for hiding this comment

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

This is the standard make file for Sphinx generated by sphinx-quickstart

#

# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build

# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
Loading
Loading