-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
DocumentationAPI: Add padding
#4557
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see you have not add padding
for all other languages.
But you make padding
mandatory.
So this would break all languages without a padding
in their style?
@@ -58,6 +60,8 @@ def __init__(self, language: str, docstyle: str, markers: (Iterable, str), | |||
'actually {}).'.format(length)) | |||
|
|||
self._metadata = metadata | |||
self._top_padding = None if padding == () else int(padding[0]) | |||
self._bottom_padding = None if padding == () else int(padding[1]) | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jayvdb This answers your question :) . .coalang
will have official standards defined.
By default top_padding
and bottom_padding
of DocComment are initialized with zero. If we don't have style defined. It will have default values. Also padding
's major motive was if a developer doesn't wants to follow official standard and decides suppose I want to have 2 blank lines at the bottom of docstring. He will set those padding variables and it will be amended by the bear part.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why split this into to variables rather than store a tuple?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using separate variables it becomes easily available at bear side. DocComment.docstyle_definition.top_padding/bottom_padding
Also they are read as strings from the file(need int). I need to get separate values in the bear part anyhow. So why not split them in the first place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can used NamedTuple to make it easier for them to be used.
The reason to keep them as a tuple is so that everywhere they are a pair, from style config to bear. consistency.
@@ -21,7 +21,7 @@ class DocstyleDefinition: | |||
|
|||
@enforce_signature | |||
def __init__(self, language: str, docstyle: str, markers: (Iterable, str), | |||
metadata: Metadata): | |||
metadata: Metadata, padding: (Iterable, str)): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to provide a default value for this new arg, thereby avoiding breaking the API?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let me see though. But I don't think that would cause any problem because load
function provides an empty tuple if it finds nothing. Which I later break into the properties of top_padding
and bottom_padding
. which is taken care by #4557 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes this breaks the API. I tried to provide a default value. But the thing is load
returns an empty tuple if it finds nothing which overwrites that default value. The best solution to providing default values through https://github.com/coala/coala/pull/4557/files#diff-bb503d77ea6d0498c9865cab08c904f4R64
# following documentation. | ||
if ((doc_comment.marker[2]+'\n') != content[end_index-1][-4:] | ||
and bottom_padding == 0): | ||
break |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is important I couldn't find any other way to do this :)
54b9fac
to
84b0386
Compare
@jayvdb We can continue our discussion here.... As |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of the examples seem to be using padding (1, 1)
.
I re-iterate what Niklas has said at coala/coala-bears#1943 (comment) , you need to be creating your own scenarios which test different valid values, even if there is no defined style with that scenario of values.
@@ -14,18 +14,19 @@ | |||
|
|||
|
|||
class DocBaseClassTest(unittest.TestCase): | |||
BaseClass = DocBaseClass() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be in method setUpClass
or setUp
.
@@ -19,6 +19,7 @@ class DocumentationCommentTest(unittest.TestCase): | |||
ReturnValue = DocumentationComment.ReturnValue | |||
|
|||
Metadata = DocstyleDefinition.Metadata | |||
BaseClass = DocBaseClass() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this (and the lines above) should be in method setUpClass
or setUp
def func(): | ||
pass | ||
|
||
## Documentation for a class. | ||
# | ||
# More details. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nope; wrong per https://www.stack.nl/~dimitri/doxygen/manual/docblocks.html#pythonblocks
(and also this fixup must undo the bad changes in the previous patch to default.py : #4549 (review) )
No, you are wrong. On https://www.python.org/dev/peps/pep-0257/ , you can see it's status is "Active". It has not been replaced. It is maintained at https://github.com/python/peps/commits/master/pep-0257.txt
Again, wrong.
A design problem, for sure. |
c2158b4
to
f9560d7
Compare
@@ -9,12 +9,9 @@ def foobar_explosion(radius): | |||
""" | |||
A nice and neat way of documenting code. | |||
:param radius: The explosion radius. """ | |||
|
|||
|
|||
def get_55(): | |||
"""A function that returns 55.""" | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this blank line is also not acceptable.
@@ -73,7 +68,6 @@ def foobar_triangle(side_A, side_B, side_C): | |||
:return: returns perimeter | |||
""" | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this blank line is also not acceptable.
@@ -43,7 +39,6 @@ def best_docstring(param1, param2): | |||
Cut to the Next Line. | |||
""" | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this blank line is also not acceptable.
start_index -= 1 | ||
while end_index < len(content) and content[end_index] == '\n': | ||
# This condition will take place if theres an inline docstring | ||
# following documentation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uhhh, I still don't understand. The padding is 0
return self._function_padding | ||
|
||
@property | ||
def docstring_type_regex(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need getters for all those members?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As everything we are fetching from .coalang
is a standard. And we don't want anyone to set those up manually. Hence setting them as getters :)
PS- Even the previous things like markers, comment's signature....etc we are fetching from .coalang
are introduced in DocstyleDefinition as getters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hm, ok... since Python doesn't have private members, the whole concept is a bit useless. But if you want to do it like that it's fine.
*(str(sign) for sign in tuple( | ||
docstyle_settings.get('docstring_type_regex', ''))) | ||
) | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
content, doc_comment_iterator) | ||
|
||
doc_comment_iterator = DocBaseClass.instantiate_docstring_type( | ||
content, doc_comment_iterator) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still unchanged and very inefficient. This method should be generator.
You have two options:
- Change
instantiate_padding
andinstantiate_docstring_type
to only process one docstring at a time, so this can become a generator. - move the functionality from
instantiate_padding
andinstantiate_docstring_type
intoextract_documentation_with_markers
and useyield from
I prefer the second option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I missed your previous comment we can do that...I see 👍
docstyle_settings['function_padding'] | ||
function_padding = cls.FunctionPadding( | ||
*(int(padding) for padding in tuple( | ||
docstyle_settings.get('function_padding', '')))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you don't have to use get
with a default value, that's why you're in a try/except block. And why are you casting this to a tuple? isn't it already an iterable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes no need to use get now 🎉
yup this isn't an iterable. we need to cast into a tuple.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is it then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when this reads function_padding
from .coalang
the values are just read as a strings.
suppose function_padding = 1, 0
This will be read as
docstyle_settings = {..., function_padding : '1, 0',...}
we cast then into a tuple ('1', '0') so they get as iterables and then we typecast them into integers.
class_padding = cls.ClassPadding('', '') | ||
|
||
try: | ||
docstyle_settings['function_padding'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is this for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup we can remove this I guess...
as now I will use docstyle_settings['function_padding']
instead of docstyle_settings.get()
which will throw a KeyError
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is what should throw the KeyError
right?
This shouldn't be it, I was just showing an example
@@ -1,3 +1,5 @@ | |||
import re |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file contains unused source code.
Origin: PyUnusedCodeBear, Section: flakes
.
The issue can be fixed by applying the following patch:
--- a/coalib/bearlib/languages/documentation/DocBaseClass.py
+++ b/coalib/bearlib/languages/documentation/DocBaseClass.py
@@ -1,4 +1,3 @@
-import re
from coalib.bearlib.languages.documentation.DocstyleDefinition import (
DocstyleDefinition)
104815c
to
a641681
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@damngamerz sorry this took so long. I'm beginning to like the overall design now 👍
Please have a look at my comments once more.
@property | ||
def class_padding(self): | ||
""" | ||
A namedtuple consisting of values about blank lines before and after |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please mention the name of all these namedtuples in the docstring. Here for example A namedtuple "ClassPadding" consisting...
, etc
A namedtuple consisting of values about blank lines before and after | ||
the documentation of ``docstring_type`` class. | ||
|
||
These values are official standard of following blank lines before and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
after
missing
A namedtuple consisting of values about blank lines before and after | ||
the documentation of ``docstring_type`` function. | ||
|
||
These values are official standard of following blank lines before and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
after
missing
*(int(padding) for padding in tuple( | ||
docstyle_settings['class_padding']))) | ||
except IndexError: | ||
class_padding = cls.ClassPadding('', '') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is the default '', ''
and not 0, 0
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because 0, 0
will mean that official defined padding is 0, 0
. So better leave the defaults to be '', ''
# Instantiate padding | ||
top_padding = 0 | ||
bottom_padding = 0 | ||
start_index = doc.range.start.line - 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please explain the -2
in a comment
bottom_padding += 1 | ||
end_index += 1 | ||
doc.top_padding = top_padding | ||
doc.bottom_padding = bottom_padding |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could remove these two lines by replacing all occurrences of top_padding
with doc.top_padding
and dito for bottom_padding
. There's no real need for a temporary variable.
end_index, | ||
1 if bottom_padding > 0 else doc.range.end.column) | ||
|
||
# Instantiate docstring_type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is inaccurate, you're just compiling regexes here
end_index = doc.range.end.line | ||
|
||
# We check for the class regex and function regex | ||
# before and after the documentation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def some_function():
"""
documentation
"""
class myPrivateClass:
pass
This docstring would falsely be identified as a type class.
I suppose to mitigate this, you'll need to specify the position of the docstring in the coalang files, too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so....we will require such a thing. Although I will add this in the test cases if it doesn't work we will have to think about the position.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes this fails. We have two ways to solve this
First one is a tricky but will work, I think we can fix this by little prioritizing the algorithm
something like:
- we search the line closest to the docstring first. (whichever has least padding will be scanned by both the regexes first.)
- If paddings are found to be equal scanning the line before starting marker with regexes first(i.e. with both
function
andclass
). Than last line will be scanned.
This will support the generic nature.
Second introducing docstring_type_position
.
If we found its written top
then we only scan top lines of the docstring with regexes or vice-versa.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Im going with the second option looks much more future proof 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
introducing docstring_type_position
is the correct solution. The other will not work, you'll only make it work for Python. Maybe docstring_position
should suffice, I doubt that styles will position the docstring on different sides for different types.
@@ -186,13 +238,38 @@ def load(cls, language: str, docstyle: str, coalang_dir=None): | |||
metadata = cls.Metadata(*(str(docstyle_settings.get(req_setting, '')) | |||
for req_setting in metadata_settings)) | |||
|
|||
try: | |||
class_padding = cls.ClassPadding( | |||
*(int(padding) for padding in tuple( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In your previous comment you said that docstyle_settings['class_padding']
is a string like "1, 0", if this is true, tuple("1, 0")
will be ("1", ",", " ", "0")
, which int
will choke on. Rather use docstyle_settings['class_padding'].split(",")
Also I'm wondering why this isn't caught by tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm now even I m wondering the same. You are correct about tuple('1,0')
will be ("1", ",", " ", "0")
but what I figured out is docstyle_settings
is a Setting
object. Now when I do tuple(docstyle_settings['class_padding'].value)
gives me ("1", ",", " ", "0")
but when I only do tuple(docstyle_settings['class_padding'])
gives me ('1', '0')
(some magic 😛 I m guessing it has to do something with the Setting
object). So I think let it be that way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uh no, please investigate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see why it's like that
coala/coalib/settings/Setting.py
Line 121 in 41e4752
class Setting(StringConverter): |
Setting
offers common data type conversions. It has list_delimeters
for list/tuple conversion. That's why we are getting ('1', '0')
while doing tuple(docstyle_settings['class_padding'])
🎉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, talk about overengineering.... anyway... it's ok then
|
||
def test_DocBaseClass_instantiate_padding_inline_PYTHON3_7(self): | ||
# To test that bottom_padding sets to nothing if docstring is | ||
# followed by inline docstring. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this the desired behavior?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we have such a case in DocStyleBear.
I don't wanna break the existing tests 😉
https://github.com/coala/coala-bears/blob/master/tests/documentation/test_files/DocumentationStyleBear/bad_file2.py.test#L21
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how is such a case handled by documentation extraction?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I mean is, if you parse and re-assemble this docstring, what will happen?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh yes! thats because....
The affected range
is always taken from starting marker to the end marker(except in case of padding). DocumentationAPI doesn't care about whats after the end marker. Hence if its followed by inline comment...It's still is at the same position after the assembling.
aed5f19
to
eee38f9
Compare
@damngamerz one last thing: The commit message needs an update: |
2457968
to
a018577
Compare
@NiklasMM Updated commit message 👍 |
7f2f30c
to
d53307c
Compare
ack d53307c |
Add `class_padding`, `function_padding` and `docstring_position` in DocstyleDefinition which are now acquired from `.coalang`. Add `top_padding` and `bottom_padding` which is automatically instantiated from DocumentationExtraction. Add `docstring_type` in DocumentationComment which will automatically determine the type of docstring from DocumentationExtraction. Add supporting test cases. Related to coala#4200
ack 070a19e |
@rultor merge |
Add
padding
in DocstyleDefinition whichare now acquired from
.coalang
. Addtop_padding
andbottom_padding
whichautomatically instantiate from
instantiate_padding
in DocBaseClass. Addsupporting test cases.
Related to #4200
For short term contributors: we understand that getting your commits well
defined like we require is a hard task and takes some learning. If you
look to help without wanting to contribute long term there's no need
for you to learn this. Just drop us a message and we'll take care of brushing
up your stuff for merge!
Checklist
them.
individually. It is not sufficient to have "fixup commits" on your PR,
our bot will still report the issues for the previous commit.) You will
likely receive a lot of bot comments and build failures if coala does not
pass on every single commit!
After you submit your pull request, DO NOT click the 'Update Branch' button.
When asked for a rebase, consult coala.io/rebase
instead.
Please consider helping us by reviewing other peoples pull requests as well:
cobot mark wip <URL>
to get it outof the review queue.
The more you review, the more your score will grow at coala.io and we will
review your PRs faster!