JuliaPy / PythonCall.jl

Python and Julia in harmony.
https://juliapy.github.io/PythonCall.jl/stable/
MIT License
715 stars 61 forks source link

viewing Julia docstrings from Python #468

Open ajwheeler opened 3 months ago

ajwheeler commented 3 months ago

Is your feature request related to a problem? Please describe. I have a julia package that most users use through juliacall. Ideally, they would be able to pull up my docstrings in jupyter notebooks, IDEs, etc.

Describe the solution you'd like Ideally, the python docstrings of julia functions would be set when they are called through juliacall. I don't know enough about the internals to have an understanding of how difficult this would be, but I have some free effort to help if it's something a non-intiate can do.

Describe alternatives you've considered I've considered wrapping my package in a custom python package that uses juliacall internally, but that seems like an inelegant solution.

cjdoris commented 3 months ago

Unfortunately this isn't possible. help(x) gets the docstring from type(x).__doc__, and since all Julia objects are wrapped with the same Python type, they all must have the same docstring.

However you can do x._jl_help() to display the Julia docstring for x.

ajwheeler commented 3 months ago

_jl_help() doesn't seem to work for me. Do you know what's going on here?

In [1]: from juliacall import Main as jl

In [2]: jl.sum
Out[2]: sum (generic function with 10 methods)

In [3]: jl.sum._jl_help()
---------------------------------------------------------------------------
JuliaError                                Traceback (most recent call last)
Cell In[3], line 1
----> 1 jl.sum._jl_help()

File ~/.julia/packages/PythonCall/wXfah/src/jlwrap/any.jl:309, in _jl_help(self, mime)
    307     return self._jl_callmethod($(pyjl_methodnum(pyjlany_display)), mime)
    308 def _jl_help(self, mime=None):
--> 309     return self._jl_callmethod($(pyjl_methodnum(pyjlany_help)), mime)
    310 def _repr_mimebundle_(self, include=None, exclude=None):
    311     return self._jl_callmethod($(pyjl_methodnum(pyjlany_mimebundle)), include, exclude)

JuliaError: MethodError: no method matching mode(::Nothing)

Closest candidates are:
  mode(!Matched::REPL.LineEdit.PrefixSearchState)
   @ REPL ~/.julia/juliaup/julia-1.10.1+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/REPL/src/LineEdit.jl:2054
  mode(!Matched::REPL.LineEdit.SearchState)
   @ REPL ~/.julia/juliaup/julia-1.10.1+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/REPL/src/LineEdit.jl:2053
  mode(!Matched::REPL.LineEdit.PromptState)
   @ REPL ~/.julia/juliaup/julia-1.10.1+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/REPL/src/LineEdit.jl:2052
  ...

Stacktrace:
 [1] (::REPL.var"#55#56"{REPL.REPLDisplay{REPL.LineEditREPL}, MIME{Symbol("text/plain")}, Base.RefValue{Any}})(io::Any)
   @ REPL ~/.julia/juliaup/julia-1.10.1+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/REPL/src/REPL.jl:263
 [2] with_repl_linfo(f::Any, repl::REPL.LineEditREPL)
   @ REPL ~/.julia/juliaup/julia-1.10.1+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/REPL/src/REPL.jl:569
 [3] display(d::REPL.REPLDisplay, mime::MIME{Symbol("text/plain")}, x::Any)
   @ REPL ~/.julia/juliaup/julia-1.10.1+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/REPL/src/REPL.jl:259
 [4] display(d::REPL.REPLDisplay, x::Any)
   @ REPL ~/.julia/juliaup/julia-1.10.1+0.aarch64.apple.darwin14/share/julia/stdlib/v1.10/REPL/src/REPL.jl:278
 [5] display(x::Any)
   @ Base.Multimedia ./multimedia.jl:340
 [6] pyjlany_help(self::Function, mime_::Py)
   @ PythonCall ~/.julia/packages/PythonCall/wXfah/src/jlwrap/any.jl:149
 [7] _pyjl_callmethod(f::Any, self_::Ptr{PythonCall.C.PyObject}, args_::Ptr{PythonCall.C.PyObject}, nargs::Int64)
   @ PythonCall ~/.julia/packages/PythonCall/wXfah/src/jlwrap/base.jl:62
 [8] _pyjl_callmethod(o::Ptr{PythonCall.C.PyObject}, args::Ptr{PythonCall.C.PyObject})
   @ PythonCall.C ~/.julia/packages/PythonCall/wXfah/src/cpython/jlwrap.jl:47

jl.sum._jl_help(mime="text/plain") fails the same way. Apologies if this is a silly error.

cjdoris commented 3 months ago

No that looks like a bug. Will take a look.

cjdoris commented 3 months ago

Bug fixed - new release coming out shortly.

ajwheeler commented 3 months ago

Fantastic!

Follow up question: what do you think about defining juliacall.jlhelp (or similar)? If I could just tell people to put

from juliacall import jlhelp

at the top of their notebooks it would solve 90% of the problem.

cjdoris commented 3 months ago

Yeah that could be nice.