How let Sphinx-autoapi show custom comment from source code - python-3.x

In a python project I generate autoapi documntation. Special comment appear in generated html files.
For instance it's working and displaying on final html page:
def do_action(self,params):
"""
This is function to do some cool stuffs.
Actually it should
"""
pass
Or
...
applicationConfig = None
"""This variable hold some important data"""
However I would like autoapi generate some custom comment into html page
For example I've got a comment in code like this:
"""These are public variable:"""
p_var1 = "segg"
p_var2 = "fos"
But this last comment not shown in generated documentation. Maybe because it hasn't connected to any definition structure in source code? (I mean neither variable declaration nor function or class declaration)
Anyway, how should force sphinx to generate html entry from any comments arrounded by triple apostrophe?

There are two options for having sphinx parse variable comments. The first is via attribute docstrings, which are specified in pep 224 to belong below the attribute that they describe, as in your first example. While it was rejected, it is the format sphinx requires in order to work correctly:
p_var1 = "segg"
"""Docstring for p_var1"""
Renders as:
Alternatively, sphinx will also pick up comments above the attribute that start with a colon and treat them like a docstring, which in some cases looks a bit better in the source code:
#: Description for p_var1
p_var1 = "segg"
Renders also as:
There is no option to pick up a comment without a module, exception, class, method, function, or variable being attached to it, becauseautodoc explicitly only considers information from docstrings (and call signatures, but that's the only exception).

Related

squeak(smalltallk) how to 'inject' string into string

I'm writing a class named "MyObject".
one of the class methods is:
addTo: aCodeString assertType: aTypeCollection
when the method is called with aCodeString, I want to add (in runtime) a new method to "MyObject" class which aCodeString is it's source code and inject type checking code into the source code.
for example, if I call addTo: assertType: like that:
a := MyObject new.
a addTo: 'foo: a boo:b baz: c
^(a*b+c)'
assertType: #(SmallInteger SmallInteger SmallInteger).
I expect that I could write later:
answer := (a foo: 2 boo: 5 baz: 10).
and get 20 in answer.
and if I write:
a foo: 'someString' boo: 5 baz: 10.
I get the proper message because 'someString' is not a SmallInteger.
I know how to write the type checking code, and I know that to add the method to the class in runtime I can use 'compile' method from Behavior class.
the problem is that I want to add the type checking code inside the source code.
I'm not really familiar with all of squeak classes so I'm not sure if I rather edit the aCodeString as a string inside addTo: assertType: and then use compile: (and I don't know how to do so), or that there is a way to inject code to an existing method in Behavior class or other squeak class.
so basically, what I'm asking is how can I inject string into an existing string or to inject code into an existing method.
There are many ways you could achieve such type checking...
The one you propose is to modify the source code (a String) so as to insert additional pre-condition type checks.
The key point with this approach is that you will have to insert the type checking at the right place. That means somehow parsing the original source (or at least the selector and arguments) so as to find its exact span (and the argument names).
See method initPattern:return: in Parser and its senders. You will find quite low level (not most beautiful) code that feed the block (passed thru return: keyword) with sap an Array of 3 objects: the method selector, the method arguments and the method precedence (a code telling if the method is connected to unary, binary or keyword message). From there, you'll get enough material for achieving source code manipulation (insert a string into another with copyReplace:from:to:with:).
Do not hesitate to write small snippets of code and execute in the Debugger (select code to debug, then use debug it menu or ALT+Shift+D). Also use the inspectors extensively to gain more insight on how things work!
Another solution is to parse the whole Abstract Syntax Tree (AST) of the source code, and manipulate that AST to insert the type checks. Normally, the Parser builds the AST, so observe how it works. From the modified AST, you can then generate new CompiledMethod (the bytecode instructions) and install it in methodDictionary - see the source code of compile: and follow the message sent until you discover generateMethodFromNode:trailer:. This is a bit more involved, and has a bad side effect that the source code is now not in phase with generated code, which might become a problem once you want to debug the method (fortunately, Squeak can used decompiled code in place of source code!).
Last, you can also arrange to have an alternate compiler and parser for some of your classes (see compilerClass and/or parserClass). The alternate TypeHintParser would accept modified syntax with the type hints in source code (once upon a time, it was implemented with type hints following the args inside angle brackets foo: x <Integer> bar: y <Number>). And the alternate TypeHintCompiler would arrange to compile preconditions automatically given those type hints. Since you will then be very advanced in Squeak, you will also create special mapping between source code index and bytecodes so as to have sane debugger and even special Decompiler class that could recognize the precondition type checks and transform them back to type hints just in case.
My advice would be to start with the first approach that you are proposing.
EDIT
I forgot to say, there is yet another way, but it is currently available in Pharo rather than Squeak: Pharo compiler (named OpalCompiler) does reify the bytecode instructions as objects (class names beginning with IR) in the generation phase. So it is also possible to directly manipulate the bytecode instructions by proper hacking at this stage... I'm pretty sure that we can find examples of usage. Probably the most advanced technic.

python - how to let others to check info in triple quotes

I am writing detailed information for each function in a class, and hope when others use my python code, they could check the info for each function, by using something like help(function_name)
For example, I have created a python file called text_preprocess.py, in this file I have created a class which includes functions.
class Preprocess():
def str_process(self, row_string):
'''
This Standford CoreNLP package requires the text input as 1 single string.
The input annotators are in you command line input.
:param row_string: The string format input for Standford CoreNLP
:return: Json format output
'''
parsed_json = self.nlp.annotate(row_string, properties={
'annotators': self.standford_annotators,
'outputFormat': 'json'
})
return parsed_json
In this function, as you can see the info is within triple quotes.
But I don't know how could other users see this info without looking into my code.
I have checked many solutions online, people use help(function_name), but it seems that they wrote the code through terminal, and then type help(function_name), many of those examples do not have class either. Using --help through command line only gives them the parameter descriptions I added through argparse....
So, if I hope others could check the info of my function without looking into the code, where and how could they do that?
Either be in the same directory as your script, or make sure your script is in one of the directories listed in sys.path (usually, the first option is easier for simple things, but if you want to do the second, use a virtualenv rather than trying to install the module system-wide).
Run pydoc3 text_preprocess to get documentation for the whole module. This recursively includes all of the items below the module, such as classes, their members, and functions.
Run pydoc3 text_preprocess.Preprocess if you just want the class.
Run pydoc3 text_preprocess.Preprocess.str_process if you just want the method.
Use Sphinx if you want nicely-formatted HTML or other formats such as PDF.
You may also want to remove that empty line at the beginning of your docstring; some docstring-parsing code may misinterpret it.
Putting triple quoted strings just below the declaration of a class or method is called documentation. You can read this using Preprocess.str_process.__doc__.

PHPStorm: 'Go to declaration' on class names in string literals

I'm using PHPStorm EAP version PS-138.940.
I have code as follows:
Config(__NAMESPACE__."\ObjectsToIdentifiers")->oldTables = array('Modules\Old\Model\DeviceStock','Modules\Old\Model\ProductPack','Modules\Old\Model\SpareStock','Modules\Old\Model\ConsumStock');
The functionality is irrelevant in this case. Important are the entries in the array. These are fully qualified class names - the leading / is omitted, but adding it doesn't solve my problem. I want to be able to click inside one of the string literals, press Ctrl+B and be redirected to the class definition.
Note that this works in ExtJS (javascript framework) where a string literal like
"MyApp.namespace.view.MyComponent"
will take me there.
Is there any way to manually configure this or do I have to submit a feature request. If so, how can I do that?
Update 1:
I created a feature request on JetBrains Youtrack: http://youtrack.jetbrains.com/issue/WI-24262
Came across this question looking for something in Storm that would let me quickly convert "\Some\ClassName" to Some\ClassName::class like an Intention or plugin, but so far have found nothing.
i'm surprised the ::class static property hasn't been mentioned. It produces the FQN of the Class, and resolves from import aliases.
The following should be a legit rewrite that the IDE can resolve:
// Same __NAMESPACE__, so no prefix needed
Config(ObjectsToIdentifiers::class)
->oldTables = [
Modules\Old\Model\DeviceStock::class,
Modules\Old\Model\ProductPack::class,
Modules\Old\Model\SpareStock::class,
Modules\Old\Model\ConsumStock::class
];
// or, if you import the classes:
use Modules\Old\Model\DeviceStock as OldDeviceStock;
// you can refer to
OldDeviceStock::class;
Unfortunately, right now if you jump-to-definition of the alias, Storm won't take you to the actual class, but where the alias is defined. Not terribly helpful, but gets you halfway since the actual class is right there.

How to get the filename and line number of a particular JetBrains.ReSharper.Psi.IDeclaredElement?

I want to write a test framework extension for resharper. The docs for this are here: http://confluence.jetbrains.net/display/ReSharper/Test+Framework+Support
One aspect of this is indicating if a particular piece of code is part of a test. The piece of code is represented as a IDeclaredElement.
Is it possible to get the filename and line number of a piece of code represented by a particular IDeclaredElement?
Following up to the response below:
#Evgeny, thanks for the answer, I wonder if you can clarify one point for me.
Suppose the user has this test open in visual studio: https://github.com/fschwiet/DreamNJasmine/blob/master/NJasmine.Tests/SampleTest.cs
Suppose the user right clicks on line 48, the "player.Resume()" expression.
Will the IDeclaredElement tell me specifically they want to run at line 48? Or is it going to give me a IDeclaredElement corresponding to the entire class, and a filename/line number range for the entire class?
I should play with this myself, but I appreciate tapping into what you already know.
Yes.
The "IDeclaredElement" entity is the code symbol (class, method, variable, etc.). It could be loaded from assembly metadata, it could be declared in source code, it could come from source code implicitly.
You can use
var declarations = declaredElement.GetDeclarations()
to get all AST elements which declares it (this could return multiple declarations for partial class, for example)
Then, for any IDeclaration, you can use
var documentRange = declaration.GetDocumentRange()
if (documentRange.IsValid())
Console.WriteLine ("File: {0} Line:{1}",
DocumentManager.GetInstance(declaration.GetSolution()).GetProjectFile(documentRange.Document).Name,
documentRange.Document.GetCoordsByOffset(documentRange.TextRange.StartOffset).Line
);
By the way, which test framework extension are you developing?
Will the IDeclaredElement tell me specifically they want to run at
line 48?
Once more: IDeclaredElement has no positions in the file. Instead, it's declaration have them.
For every declaration (IDeclaration is a regular AST node) there is range in document which covers it. In my previous example, I used TextRange.StartOffset, though you can use TextRange.EndOffset.
If you need more prcise position in the file, please traverse AST tree, and check the coordinates in the document for specific expression/statement

python: manipulating __dict__ of the class

(All in ActivePython 3.1.2)
I tried to change the class (rather than instance) attributes. The __dict__ of the metaclass seemed like the perfect solution. But when I tried to modify, I got:
TypeError: 'dict_proxy' object does
not support item assignment
Why, and what can I do about it?
EDIT
I'm adding attributes inside the class definition.
setattr doesn't work because the class is not yet built, and hence I can't refer to it yet (or at least I don't know how).
The traditional assignment doesn't work because I'm adding a large number of attributes, whose names are determined by a certain rule (so I can't just type them out).
In other words, suppose I want class A to have attributes A.a001 through A.a999; and all of them have to be defined before it's fully built (since otherwise SQLAlchemy won't instrument it properly).
Note also that I made a typo in the original title: it's __dict__ of a regular class, not a metaclass, that I wanted to modify.
The creation of a large number of attributes following some rule smells like something is seriously wrong. I'd go back and see if there isn't a better way of doing that.
Having said there here is "Evil Code" (but it'll work, I think)
class A:
locals()['alpha'] = 1
print A.alpha
This works because while the class is being defined there is a dictionary that tracks the local variables you are definining. These local variables eventually become the class attributes. Be careful with locals as it won't necessarily act "correctly." You aren't really supposed to be modifying locals, but it does seem to work when I tried it.
Instead of using the declarative syntax, build the table seperately and then use mapper on it. see http://www.sqlalchemy.org/docs/05/ormtutorial.html# I think there is just no good way to add computed attributes to class while defining it.
Alternatively, I don't know whether this will work but:
class A(object):
pass
A.all_my_attributes = values
class B(declarative_base, A):
pass
might possibly work.
I'm not too familiar with how 3 treats dict but you might be able to circumvent this problem by simply inheriting the dictionary class like so:
class A(dict):
def __init__(self,dict_of_args):
self['key'] = 'myvalue'
self.update(dict_of_args)
# whatever else you need to do goes here...
A() can be referenced like so:
d = {1:2,3:4}
obj = A(mydict)
print obj['test'],obj[3] # this will print myvalue and 4
Hope this helps.

Resources