-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
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
[Feature Request] Support for extending documentation using ?
#13860
Comments
Apologies for the late reply. If my understanding is correct, you want o be able to define class Bar:
def show_documentation(self, obj, attrname):
"""
:return:
Docstring of attribute `attrname` on object `obj`
:rtype:
str
"""
if obj is self and attrname is 'baz':
return "this is a baz it is the bazified value of the Bar instance
Ir you you want the hook to be external: ip = get_ipython()
ip.register_doc_hook(...) I do have some concerns about the first instance, similar things have longed been discussed, and the consensus is that we do not want to have object-controlled code execution when showing documentation. This is a security risk, and if documentation can start to have side effects it will create other problems, like impossibility to see documentation when the kernel is busy. This is already a problem when even with just For the second This is a larger project (https://github.com/jupyter/papyri) I am working on that completely rework how current documentation work, and would allow more dynamic (and html browsable) documentation within notebook. Though this is not a small project. I think you are more meaning the second one, but I'm slightly worried of having it be a cusotmizable hook. Can you give me an example of why you would like it to be different on a per object basis ? Would something like simply looking up |
One other issue I can have is that with the above,
|
Thanks for the response. What I wanted was some way to know -
Then, we will do "minor computation" and return a string. Yes, initially I thought it could be an external hook that receives the object and the attribute name. But, given the points you mentioned above I think we can explore this simple solution -
I am assuming you mean defining a class variable. This may not be sufficient because the no. of attributes can be high and we do not want to hard-code it on the class. Maybe a bit more generic than this - class Bar:
__custom_documentations__ = (Dict-like-object) So, somewhere here, it can check if In this case, user (we) would have to do something like below, but it should be fine - class DictLike:
def __getitem__(self, k):
... "the minor computation at runtime to generate docstring" ..
return "documentation for k"
class Bar:
__custom_documentations__ = DictLike() Above solution still limits it to class level, it would be much better if we have it at object level e.g. defining a custom method
Totally agree here. We should leave it totally up to the user to not have side effects / execute arbitrary code if they are using this feature. getdoc method is one such example, where user can execute arbitrary code on
This should be fine. We need not handle the second case Opens for suggestions!! cc: @mlucool if he has some thoughts on this. |
In view of working with ipython#13860, some cleanup inspect to be properly typed, and using stricter datastructure. Instead of dict we now use dataclasses, this will make sure that fields type and access can be stricter and verified not only at runtime, but by mypy
In view of working with ipython#13860, some cleanup inspect to be properly typed, and using stricter datastructure. Instead of dict we now use dataclasses, this will make sure that fields type and access can be stricter and verified not only at runtime, but by mypy
In view of working with ipython#13860, some cleanup inspect to be properly typed, and using stricter datastructure. Instead of dict we now use dataclasses, this will make sure that fields type and access can be stricter and verified not only at runtime, but by mypy
Thanks for your patience. I've been looking at the code, and it looks like this should be doable with some refactor, I need to thread some extra information here and there and have some refactor, but it seem the code already has a notion of object and its parent. in the case of This information is just not handled everywhere, but once that's done, it shoudl be straitforward to look at wether There is some minimal complexity due to sphinxify that tries to convert docs to html, and minor changes to public methods. I'll do some refactor/cleanup first. |
In view of working with ipython#13860, some cleanup inspect to be properly typed, and using stricter datastructure. Instead of dict we now use dataclasses, this will make sure that fields type and access can be stricter and verified not only at runtime, but by mypy
In view of working with #13860, some cleanup inspect to be properly typed, and using stricter datastructure. Instead of dict we now use dataclasses, this will make sure that fields type and access can be stricter and verified not only at runtime, but by mypy
Misc questions/interogation while I'm working on it:
|
Base for ipython#13860, so that object can be queried for documentation on their fields/properties. Typically this allows the following, to extend the doc documentation when requesting information on a field. In [1]: class DictLike: ...: def __getitem__(self, k): ...: if k.startswith('f'): ...: return "documentation for k" ...: else: ...: raise KeyError ...: ...: class Bar: ...: __custom_documentations__ = DictLike() ...: ...: faz = 1 ...: ...: ...: @Property ...: def foo(self): ...: return 1 ...: b = Bar() ...: b.faz?
Thanks @Carreau for working on this.
It should always show docstring from class Bar:
@property
def foo(self):
"""
Docstring for foo
"""
return self._foo
@foo.setter
def foo(self, v):
self._foo = v
bar = Bar()
bar.foo? # Gives 'Docstring for foo' Now, doing below still gives 'Docstring for foo' and not for a DataFrame's docstring: bar.foo = DataFrame(range(10))
bar.foo? So, with class DictLike:
def __getitem__(self, k):
if k == 'foo':
return "Docstring for foo"
raise KeyError
class Bar:
__custom__documentations__ = DictLike()
bar = Bar()
bar.foo? # Gives 'Docstring for foo' Now below should still query bar.foo = DataFrame(range(10))
bar.foo? # Should still give 'Docstring for foo' This way it will be consistent before and after doing
This is an interesting thing. For now, simply docstring should do and type can be class DictLike:
def __getitem__(self, k):
if k == 'foo':
return "Docstring for foo"
raise KeyError
class Bar:
__custom__documentations__ = DictLike()
bar = Bar() Now doing Type: property
String form: <property object at 0x7efd0c01a4d0> (not sure about this line..?)
Docstring: Docstring for foo
Yes, only Open to other ideas and thoughts!! |
Base for ipython#13860, so that object can be queried for documentation on their fields/properties. Typically this allows the following, to extend the doc documentation when requesting information on a field. In [1]: class DictLike: ...: def __getitem__(self, k): ...: if k.startswith('f'): ...: return "documentation for k" ...: else: ...: raise KeyError ...: ...: class Bar: ...: __custom_documentations__ = DictLike() ...: ...: faz = 1 ...: ...: ...: @Property ...: def foo(self): ...: return 1 ...: b = Bar() ...: b.faz?
Base for ipython#13860, so that object can be queried for documentation on their fields/properties. Typically this allows the following, to extend the doc documentation when requesting information on a field. In [1]: class DictLike: ...: def __getitem__(self, k): ...: if k.startswith('f'): ...: return "documentation for k" ...: else: ...: raise KeyError ...: ...: class Bar: ...: __custom_documentations__ = DictLike() ...: ...: faz = 1 ...: ...: ...: @Property ...: def foo(self): ...: return 1 ...: b = Bar() In [2]: b.faz?
Base for #13860, so that object can be queried for documentation on their fields/properties. Typically this allows the following, to extend the doc documentation when requesting information on a field. ```python class DictLike: def __getitem__(self, k): if k.startswith('f'): return "documentation for k" else: raise KeyError class Bar: __custom_documentations__ = DictLike() faz = 1 @Property def foo(self): return 1 b = Bar() b.faz? ```
Closing as this was released with IPython 8.12. Thanks @Carreau. |
IPython's feature to show documentation using
foo.bar?
is very helpful. It would be great feature addition to provide support for dynamically showing documentation when saybar
in not an actually property (defined with@property
and having docstring) or attribute onfoo
, but can be set onfoo
.Solution for showing dynamic tab completions
As an example, for showing tab suggestions
__dir__
can be defined on a class as per #7245 (comment). But, there does not seem an equivalent to make docstring using?
also work.Possible solution
A custom hook can be provided (may be with better name) which users can use something like -
So, if someone does
foo[2].bar.baz?
and ifbaz
is not found with@property
onbar
, thenshow_documentation(self, <bar object (preferably) or class of bar object>, 'baz')
is invoked.Additionally, it would be great if after doing say
foo[2].bar.baz = 5
it continues to show the above documentation and not the documentation forint
.This is just one solution, open for better ideas!
The text was updated successfully, but these errors were encountered: