In my editor (notepad++) in Python script edit mode, a line
## is this a special comment or what?
Turns a different color (yellow) than a normal #comment.
What's special about a ##comment vs a #comment?
From the Python point of view, there's no difference. However, Notepad++'s highlighter considers the ## sequence as a STRINGEOL, which is why it colours it this way. See this thread.
I thought the difference had something to do with usage:
#this is a code block header
vs.
##this is a comment
I know Python doesn't care one way or the other, but I thought it was just convention to do it that way.
Also, in a different situations:
Comment whose first line is a double hash:
This is used by doxygen and Fredrik Lundh's PythonDoc. In doxygen,
if there's text on the line with the double hash, it is treated as
a summary string. I dislike this convention because it seems too
likely to result in false positives. E.g., if you comment-out a
region with a comment in it, you get a double-hash.
Related
I want to be able to control vim/neovim on a per-key basis with python scripting. There is a function called feedkeys in the python vim module (vim.feedkeys) that is nearly what I want. However, I haven't been able to figure out how to send things like function keys, arrow keys, pgup, pgdown etc as it always takes my strings completely literally.
As per the documentation for vim's feedkeys (vimscript version, not python)
feedkeys("\<CR>") simulates pressing of the <Enter> key. But feedkeys('\<CR>') pushes 5 characters.
Things I've tried with the python counterpart that haven't worked (note, <CR> is just an example; I know I can use \n for that. Nonetheless, this should simulate an enter keypress):
vim.feedkeys("\<CR>")
vim.feedkeys("<CR>")
vim.feedkeys("\<CR\>")
vim.call("feedkeys", "\<CR>")
vim.call("feedkeys", '"\<CR>"')
All of these were interpreted literally. I want to do something like
vim.feedkeys("\<F5>") etc. Any ideas?
This isn't ideal, but it solves my issue well enough:
vim.command('call feedkeys("\<F5>")')
In case this is useful to anyone, I've written a general function that will handle the \<> escapes as well as double-quotes:
def fkeys(text):
firstsub = True
for sub in text.split('"'):
if firstsub:
firstsub = False
else:
vim.feedkeys('"')
vim.command(f'call feedkeys("{sub}")')
Sorry for being Captain Obvious, but it doesn't work, because Python is not VimScript.
See :h nvim_replace_termcodes() and :h nvim_feedkeys() for a complete example. In case of <CR>, simply byte value of 13 will do.
You don't, because the interpretation of something like "\<CR>" is a function of VimL string literals. In other words, feedkeys("\<CR>") is the same thing as (probably) feedkeys("\x0d") — the function doesn't see the difference, the interpretation happens at a source code level. Naturally, Python doesn't have the same feature in the same way.
If you don't want to figure out what the escape sequence is for F5 and code it into your Python script, perhaps you could use vim.eval() to eval a VimL expression, e.g. vim.eval(r'feedkeys("\<F5>")').
Am I correct in thinking that that Python doesn't have a direct equivalent for Perl's __END__?
print "Perl...\n";
__END__
End of code. I can put anything I want here.
One thought that occurred to me was to use a triple-quoted string. Is there a better way to achieve this in Python?
print "Python..."
"""
End of code. I can put anything I want here.
"""
The __END__ block in perl dates from a time when programmers had to work with data from the outside world and liked to keep examples of it in the program itself.
Hard to imagine I know.
It was useful for example if you had a moving target like a hardware log file with mutating messages due to firmware updates where you wanted to compare old and new versions of the line or keep notes not strictly related to the programs operations ("Code seems slow on day x of month every month") or as mentioned above a reference set of data to run the program against. Telcos are an example of an industry where this was a frequent requirement.
Lastly Python's cult like restrictiveness seems to have a real and tiresome effect on the mindset of its advocates, if your only response to a question is "Why would you want to that when you could do X?" when X is not as useful please keep quiet++.
The triple-quote form you suggested will still create a python string, whereas Perl's parser simply ignores anything after __END__. You can't write:
"""
I can put anything in here...
Anything!
"""
import os
os.system("rm -rf /")
Comments are more suitable in my opinion.
#__END__
#Whatever I write here will be ignored
#Woohoo !
What you're asking for does not exist.
Proof: http://www.mail-archive.com/python-list#python.org/msg156396.html
A simple solution is to escape any " as \" and do a normal multi line string -- see official docs: http://docs.python.org/tutorial/introduction.html#strings
( Also, atexit doesn't work: http://www.mail-archive.com/python-list#python.org/msg156364.html )
Hm, what about sys.exit(0) ? (assuming you do import sys above it, of course)
As to why it would useful, sometimes I sit down to do a substantial rewrite of something and want to mark my "good up to this point" place.
By using sys.exit(0) in a temporary manner, I know nothing below that point will get executed, therefore if there's a problem (e.g., server error) I know it had to be above that point.
I like it slightly better than commenting out the rest of the file, just because there are more chances to make a mistake and uncomment something (stray key press at beginning of line), and also because it seems better to insert 1 line (which will later be removed), than to modify X-many lines which will then have to be un-modified later.
But yeah, this is splitting hairs; commenting works great too... assuming your editor supports easily commenting out a region, of course; if not, sys.exit(0) all the way!
I use __END__ all the time for multiples of the reasons given. I've been doing it for so long now that I put it (usually preceded by an exit('0');), along with BEGIN {} / END{} routines, in by force-of-habit. It is a shame that Python doesn't have an equivalent, but I just comment-out the lines at the bottom: extraneous, but that's about what you get with one way to rule them all languages.
Python does not have a direct equivalent to this.
Why do you want it? It doesn't sound like a really great thing to have when there are more consistent ways like putting the text at the end as comments (that's how we include arbitrary text in Python source files. Triple quoted strings are for making multi-line strings, not for non-code-related text.)
Your editor should be able to make using many lines of comments easy for you.
What is the proper syntax for a hanging indent for a method with multiple parameters and type hinting?
Align under first parameter
def get_library_book(self,
book_id: str,
library_id: str
)-> Book:
Indent one level beneath
def get_library_book(
self,
book_id: str,
library_id: str
) -> Book:
PEP8 supports the Indent one level beneath case, but does not specify if Align under first parameter is allowed. It states:
When using a hanging indent the following should be considered; there
should be no arguments on the first line and further indentation
should be used to clearly distinguish itself as a continuation line.
PEP8 has many good ideas in it, but I wouldn't rely on it to decide this kind of question about whitespace. When I studied PEP8's recommendations on whitespace, I found them to be inconsistent and even contradictory.
Instead, I would look at general principles that apply to nearly all programming languages, not just Python.
The column alignment shown in the first example has many disadvantages, and I don't use or allow it in any of my projects.
Some of the disadvantages:
If you change the function name so its length is different, you must realign all of the parameters.
When you do that realignment, your source control diffs are cluttered with unnecessary whitespace changes.
As the code is updated and maintained, it's likely that you'll miss some of the alignment when renaming variables, leading to misaligned code.
You get much longer line lengths.
The alignment doesn't work in a proportional font. (Yes, some developers prefer proportional fonts, and if you avoid column alignment, your code will be equally readable in monospaced or proportional fonts.)
It gets even worse if you use column alignment in more complex cases. Consider this example:
let mut rewrites = try_opt!(subexpr_list.iter()
.rev()
.map(|e| {
rewrite_chain_expr(e,
total_span,
context,
max_width,
indent)
})
.collect::<Option<Vec<_>>>());
This is Rust code from the Servo browser, whose coding style mandates this kind of column alignment. While it isn't Python code, exactly the same principles apply in Python or nearly any language.
It should be apparent in this code sample how the use of column alignment leads to a bad situation. What if you needed to call another function, or had a longer variable name, inside that nested rewrite_chain_expr call? You're just about out of room unless you want very long lines.
Compare the above with either of these versions which use a purely indentation-based style like your second Python example:
let mut rewrites = try_opt!(
subexpr_list
.iter()
.rev()
.map( |e| {
rewrite_chain_expr( e, total_span, context, max_width, indent )
})
.collect::<Option<Vec<_>>>()
);
Or, if the parameters to rewrite_chain_expr were longer or if you just wanted shorter lines:
let mut rewrites = try_opt!(
subexpr_list
.iter()
.rev()
.map( |e| {
rewrite_chain_expr(
e,
total_span,
context,
max_width,
indent
)
})
.collect::<Option<Vec<_>>>()
);
In contrast to the column-aligned style, this pure indentation style has many advantages and no disadvantages at all.
Appart from Terrys answer, take an example from typeshed which is the project on Python's GitHub for annotating the stdlib with stubs.
For example, in importlib.machinery (and in other cases if you look) annotations are done using your first form, for example:
def find_module(cls, fullname: str,
path: Optional[Sequence[importlib.abc._Path]]
) -> Optional[importlib.abc.Loader]:
Read the previous line of PEP 8 more carefully, the part before "or using a hanging indent".
Continuation lines should align wrapped elements either vertically using Python's implicit line joining inside parentheses, brackets and braces, or using a hanging indent.
This is intended to cover the first "yes' example, and your first example above.
# Aligned with opening delimiter.
foo = long_function_name(var_one, var_two,
var_three, var_four)
In TextMate 1.5.10 r1623, you get little arrows that allow you to fold method blocks:
Unfortunately, if you have a multi-lined Python comment, it doesn't recognize it, so you can't fold it:
def foo():
"""
How do
I fold
these comments?
"""
print "bar"
TextMate has this on their site on how to customize folding: http://manual.macromates.com/en/navigation_overview#customizing_foldings
...but I'm not skilled in regex enough to do anything about it. TextMate uses the Oniguruma regex API, and I'm using the default Python.tmbundle updated to the newest version via GetBundles.
Does anyone have an idea of how to do this? Thanks in advance for your help! :)
Adding the default foldingStartMarker and foldingStopMarker regex values for Python.tmbundle under the Python Language in Bundle Editor:
foldingStartMarker = '^\s*(def|class)\s+([.a-zA-Z0-9_ <]+)\s*(\((.*)\))?\s*:|\{\s*$|\(\s*$|\[\s*$|^\s*"""(?=.)(?!.*""")';
foldingStopMarker = '^\s*$|^\s*\}|^\s*\]|^\s*\)|^\s*"""\s*$';
It appears that multi-line comment folding does work in TextMate, but your must line up your quotes exactly like so:
""" Some sort of multi
line comment, which needs quotes
in just the right places to work. """
That seems to do it:
According to this Textmate Mailing list thread, if you follow it to the end, proper code folding for Python is not supported. Basically, regular expressions as implemented in the foldingStartMarker and foldingStopMarker do not allow for captures, thus the amount of spacing at the beginning of the "end fold" cannot be matched to the "begin fold".
The issue is not finally and officially addressed by Textmate's creator, Allan Odgaard; however since the thread is from 2005, I assume it is a dead issue, and not one that will be supported.
I realize there's a way in Vim to hide/fold lines, but what I'm looking for is a way to select a block of text and have Vim wrap lines at or near column 80.
Mostly I want to use this on comments in situations where I'm adding some text to an existing comment that pushes it over 80 characters. It would also be nice if it could insert the comment marker at the beginning of the line when it wraps too. Also I'd prefer the solution to not autowrap the entire file since I have a particular convention that I use when it comes to keeping my structured code under the 80 character line-length.
This is mostly for Python code, but I'm also interested in learning the general solution to the problem in case I have to apply it to other types of text.
gq
It's controlled by the textwidth option, see ":help gq" for more info.
gq will work on the current line by default, but you can highlight a visual block with Ctrl+V and format multiple lines / paragraphs like that.
gqap does the current "paragraph" of text.
Take a look at ":help =" and ":help 'equalprg"
:set equalprg=fold
and in normal mode == filters the current line through the external fold program. Or visual-select something and hit =