Is there anything that cannot appear inside parentheses? - python

I was intrigued by this answer to my question about getting vim to highlight unmatched brackets in python code. Specifically, I'm talking about the second part of his answer where he mentions that the C syntax highlighting is actually flagging as an error any instance of curly braces inside parens. It is an unobtrusive cue that you have unclosed parens when all of your downstream curly braces light up in red.
That trick works because C syntax doesn't allow curly braces inside parentheses. To satisfy my (morbid?) curiosity, can I do something similar with python code? Is there anything in python syntax that isn't legal inside parentheses?
Note: I'm not trolling for a better answer to my other question (there are plenty of good answers there already). I'm merely curious if this trick is even possible with python code.

Any Python statement (import, if, for, while, def, class etc.) cannot be in the parentheses:
In [1]: (import sys)
------------------------------------------------------------
File "<ipython console>", line 1
(import sys)
^
<type 'exceptions.SyntaxError'>: invalid syntax

Here's an exact answer:
http://docs.python.org/reference/expressions.html#grammar-token-expression_list
http://docs.python.org/reference/compound_stmts.html#function

I'm not sure what are you trying to do, but how about "def" or "class"?
this snippet is valid when it's not inside parenthesis
class dummy: pass

Related

Python f-string: replacing newline/linebreak [duplicate]

This question already has answers here:
How can I use newline '\n' in an f-string to format output?
(7 answers)
Closed last month.
First off all, sorry: I'm quite certain this might be a "duplicate" but I didn't succeed finding the right solution.
I simply want to replace all linebreaks within my sql-code for logging it to one line, but Python's f-string doesn't support backslashes, so:
# Works fine (but is useless ;))
self.logger.debug(f"Executing: {sql.replace( 'C','XXX')}")
# Results in SyntaxError:
# f-string expression part cannot include a backslash
self.logger.debug(f"Executing: {sql.replace( '\n',' ')}")
Of course there are several ways to accomplish that before the f-string, but I'd really like to keep my "log the line"-code in one line and without additional helper variables.
(Besides I think it's a quite stupid behavior: Either you can execute code within the curly brackets or you cant't...not "you can, but only without backslashes"...)
This one isn't a desired solution because of additional variables:
How to use newline '\n' in f-string to format output in Python 3.6?
General Update
The suggestion in mkrieger1s comment:
self.logger.debug("Executing %s", sql.replace('\n',' '))
Works fine for me, but as it doesn't use f-strings at all (beeing that itself good or bad ;)), I think I can leave this question open.
I found possible solutions
from os import linesep
print(f'{string_with_multiple_lines.replace(linesep, " ")}')
Best,
You can do this
newline = '\n'
self.logger.debug(f"Executing: {sql.replace( newline,' ')}")
don't use f-strings, especially for logging
assign the newline to a constant and use that, which you apparently don't want to
use an other version of expressing a newline, chr(10) for instance
(Besides I think it's a quite stupid behavior: Either you can execute code within the curly brackets or you cant't...not "you can, but only without backslashes"...)
Feel free to take a shot at fixing it, I'm pretty sure this restriction was not added because the PEP authors and feature developers wanted it to be a pain in the ass.

how does IPython's ? (question mark) operator actually work?

So i was thinking that in order to implement such a feature in a console application , where appending a question mark at the end of a function name will pour out it's doc string , i would have probably used a feature like metaclasses , where upon definition/import , i'd duplicate all the module member names and produce new ones just for typing out doc strings.
Then i noticed that you don't need actual parenthesis to call the helper functions and python doesn't actually allow you to put a question mark at the end of the function name anyway.... So is this done in python or am i just wasting my time trying to figure this out?
Thanks in advance
It's not done the way you're imagining. ipython reads your command prompt input as a line of text, so it has a chance to check if it ends with a question mark before it passes it on to eval (or whatever). If it does, it runs help(name) instead of what you typed.
AST looks a little heavy-duty, but you can get a feel for how this works by checking out the module code. It gives you a lightweight interpreter that you can extend with syntax of this sort if you want.
Have a look at the IPython.core.inputsplitter module for the code that parses the raw input line for things like ?, !, /, %, etc.
ipython uses AST, you can customize the syntax parsing and create a new ipython fork.
may help

Emacs Python.el, Syntax Highlighting Quirks

I'm using python.el version 0.23.1 for Emacs right now. The syntax highlighting seems to be a bit off -- any variable name containing an underscore followed by a keyword will result in the keyword being highlighted. Example, "foo_list" will result in "list" being highlighted.
More for my own understanding of Emacs-Lisp than anything (it's not a big deal) how do I go about fixing that. Here is where I think the relevant code is in "python.el", lines 312-318. I suspect the problem is with the definition of "symbol-start" but I have no idea what that name refers to.
(defvar python-font-lock-keywords
;; Keywords
`(,(rx symbol-start
(or "and" "del" "from" "not" "while" "as" "elif" "global" "or" "with"
"assert" "else" "if" "pass" "yield" "break" "except" "import"
"print" "class" "exec" "in" "raise" "continue" "finally" "is"
"return" "def" "for" "lambda" "try" "self")
symbol-end)
One thing I've struggled with in Emacs-Lisp so far is that I am finding it difficult in situations like these to follow names back to their definitions.
Thanks in advance!
When you say you're using python-mode 0.23.1, do you mean the one that comes bundled with Emacs or this one: http://launchpad.net/python-mode ? (which seems to be on version 6.something)
The reason I'm asking is that I can't reproduce what you're seeing. In an empty python buffer, I inserted
def x ():
a_list =3
and "list" is only highlighted when I delete the "a_". I'm using the version bundled with Emacs, with a snapshot version of Emacs so this might be the difference?
Incidentally, the font lock rule that you quote looks right to me: maybe the problem is that in your version "_" isn't set to have symbol syntax? You can check by typing
M-: (string (char-syntax ?_))
when in a python buffer. You should get "_" (which means symbol). If you get "." (punctuation) or something else weird, that probably explains what's gone wrong.

Is it true that I can't use curly braces in Python?

I was reading that Python does all it's "code blocks" by indentation, rather than with curly braces. Is that right? So functions, if's and stuff like that all appear without surrounding their block with curly braces?
You can try to add support for braces using a future import statement, but it's not yet supported, so you'll get a syntax error:
>>> from __future__ import braces
File "<stdin>", line 1
SyntaxError: not a chance
Correct for code blocks. However, you do define dictionaries in Python using curly braces:
a_dict = {
'key': 'value',
}
Ahhhhhh.
Yes. Curly braces are not used. Instead, you use the : symbol to introduce new blocks, like so:
if True:
do_something()
something_else()
else:
something()
Python with Braces is a variant of python that lets you do exactly that.
It's a project that I've been working on lately together with my friend.
Use Whyton:
http://writeonly.wordpress.com/2010/04/01/whython-python-for-people-who-hate-whitespace/
Yup :)
And there's (usually) a difference between 4 spaces and a tab, so make sure you standardize the usage ..
Yes.
if True:
#dosomething
else:
#dosomething else
#continue on with whatever you were doing
Basically, wherever you would've had an opening curly brace, use a colon instead. Unindent to close the region. It doesn't take long for it to feel completely natural.
>>> from __future__ import braces
File "<stdin>", line 1
SyntaxError: not a chance
Well that explains a lot.
Note however, that Python does natively support curly brace-d code blocks! Take a look at below:
if x: #{
x += 1
#}
For Ada or Pascal programmers, I take delight in revealing to you:
if x: #BEGIN
...
#END
Taken from the docs:
Python's parser is also sophisticated enough to recognize mixed
notations, and it will even catch missing beginning or end
delimiters and correct the program for the user. This allows the
following to be recognized as legal Python:
if x: #BEGIN
x = x + 1
#}
And this, for Bash users:
if x:
x=99
#fi
Even better, for programmers familiar with C, C++, etc. you can omit the curly braces completely for only one statement:
if x:
do_stuff()
Beautiful. As mentioned before, Python can also automatically correct code with incorrect delimiters, so this code is also legal:
if x:
do_a_hundred_or_more_statements()
x = x + 1
print(x)
As this must make you love Python even more, I send you off with one last quote from the docs.
Now as you can see from this series of examples, Python has
advanced the state of the art of parser technology and code
recognition capabilities well beyond that of the legacy languages.
It has done this in a manner which carefully balances good coding
style with the need for older programmers to feel comfortable with
look of the language syntax.
The only limitation is that these special delimiters be preceded by a hashtag symbol.
Python does not use curly braces for code blocks:
>>> while True {
File "<stdin>", line 1
while True {
^
SyntaxError: invalid syntax
>>> from __future__ import braces
File "<stdin>", line 1
SyntaxError: not a chance
(Notice the "not a chance" message – this is an Easter egg reflecting this design decision.)
As a language designed to be easy to use and read, Python uses colons and indentation to designate code blocks. Defining code blocks by indentation is unusual and can come as a surprise to programmers who are used to languages like C++ and C# because these (and many other languages) don't care about extra whitespace or indentation. This rule is intended to increase readability of Python code, at the cost of some of the programmer's freedom to use varying amounts of whitespace.
An increase in the indentation level indicates the start of a code block, while a decrease indicates the end of the code block. By convention, each indentation is four spaces wide.
Here's a simple example which sums all the integers from 0 to 9. Note that ranges in Python include the first value, up to but not including the last value:
j = 0
for i in range(0, 10):
j += i
print(j)
Yes you can use this library/package { Py }
Use curly braces instead of indenting, plus much more sugar added to Python's syntax.
https://pypi.org/project/brackets/
// Use braces in Python!
def fib(n) {
a, b = 0, 1
while (a < n) {
print(a, end=' ')
a, b = b, a+b
}
print()
}
/*
Powerful anonymous functions
*/
print([def(x) {
if(x in [0, 1]) {
return x
};
while (x < 100) {
x = x ** 2
};
return x
}(x) for x in range(0, 10)])
As others have mentioned, you are correct, no curly braces in Python. Also, you do not have no end or endif or endfor or anything like that (as in pascal or ruby). All code blocks are indentation based.
Yes, code blocks in Python are defined by their indentation. The creators of Python were very interested in self-documenting code. They included indentation in the syntax as a way of innately enforcing good formatting practice.
I programmed in Python for a few years and became quite fond of its code structure because it really is easier. Have you ever left out a closing curly brace in a large program and spent hours trying to find it? Not a problem in Python. When I left that job and had to start using PHP, I really missed the Python syntax.
I will give some thoughts about this question.
Admittedly at first I also thought it is strange to write code without curly braces. But after using Python for many years, I think it is a good design.
First, do we really need curly braces? I mean, as a human. If you are allowed to use curly braces in Python, won't you use indentation anymore? Of course, you will still use indentation! Because you want to write readable code, and indentation is one of the key points.
Second, when do we really need curly braces? As far as I think, we only strictly need curly braces when we need to minify our source code files. Like minified js files. But will you use Python in a situation that even the size of source code is sensitive? Also as far as I think, you won't.
So finally, I think curly braces are somehow like ;. It is just a historical issue, with or without it, we will always use indentation in Python.
In Python, four spaces() are used for indentation in place of curly braces ({). Though, curly braces are used at few places in Python which serve different purpose:
Initialize a non-empty set (unordered collection of unique elements):
fuitBasket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
Citation
Initialize an empty dictionary (key-value pairs):
telephoneNumbers = {}
Initialize a non-empty dictionary (key-value pairs):
telephoneNumbers = {'jack': 4098, 'sape': 4139}
Citation
In relation to format string, curly braces take on a different meaning. See https://docs.python.org/3/library/string.html?highlight=curly :
Format strings contain “replacement fields” surrounded by curly braces
{}. Anything that is not contained in braces is considered literal
text, which is copied unchanged to the output. If you need to include
a brace character in the literal text, it can be escaped by doubling:
{{ and }}.

How can I convert a Perl regex with named groups to Python?

I am trying to convert the following Perl regex I found in the Video::Filename Perl module to a Python 2.5.4 regex to parse a filename
# Perl > v5.10
re => '^(?:(?<name>.*?)[\/\s._-]*)?(?<openb>\[)?(?<season>\d{1,2})[x\/](?<episode>\d{1,2})(?:-(?:\k<season>x)?(?<endep>\d{1,2}))?(?(<openb>)\])(?:[\s._-]*(?<epname>[^\/]+?))?$',
I would like to use named groups too, and I know in Python the regex extension for named groups is different, but I am not 100% sure on the syntax.
This is what I tried:
# Python (not working)
r = re.compile(r'^(?:(?P<name>.*?)[\/\s._-]*)?(?P<openb>\[)?(?P<season>\d{1,2})[x\/](?P<episode>\d{1,2})(?:-(?:\kP<season>x)?(?P<endep>\d{1,2}))?(?(P<openb>)\])(?:[\s._-]*(?P<epname>[^\/]+?))?$')
The error I get:
raise error, v # invalid expression
sre_constants.error: bad character in group name
For example, this one I managed to convert and it works. But the one above I can't seem to get right. I get a compilation error in Python.
# Perl:
re => '^(?:(?<name>.*?)[\/\s._-]+)?(?:s|se|season|series)[\s._-]?(?<season>\d{1,2})[x\/\s._-]*(?:e|ep|episode|[\/\s._-]+)[\s._-]?(?<episode>\d{1,2})(?:-?(?:(?:e|ep)[\s._]*)?(?<endep>\d{1,2}))?(?:[\s._]?(?:p|part)[\s._]?(?<part>\d+))?(?<subep>[a-z])?(?:[\/\s._-]*(?<epname>[^\/]+?))?$',
# Python (working):
r = re.compile(r'^(?:(?P<name>.*?)[\/\s._-]+)?(?:s|se|season|series)[\s._-]?(?P<season>\d{1,2})[x\/\s._-]*(?:e|ep|episode|[\/\s._-]+)[\s._-]?(?P<episode>\d{1,2})(?:-?(?:(?:e|ep)[\s._]*)?(?P<endep>\d{1,2}))?(?:[\s._]?(?:p|part)[\s._]?(?P<part>\d+))?(?P<subep>[a-z])?(?:[\/\s._-]*(?P<epname>[^\/]+?))?$')
I am not sure where to start looking.
There are 2 problems with your translation. First of all, the second mention of openb has extra parenthesis around it making it a conditional expression, not a named expression.
Next is that you didn't translate the \k<season> backreference, Python uses (P=season) to match the same. The following compiles for me:
r = re.compile(r'^(?:(?P<name>.*?)[\/\s._-]*)?(?P<openb>\[)?(?P<season>\d{1,2})[x\/](?P<episode>\d{1,2})(?:-(?:(?P=season)x)?(?P<endep>\d{1,2}))?(?(openb)\])(?:[\s._-]*(?P<epname>[^\/]+?))?$')
If I were you, I'd use re.VERBOSE to split this expression over multiple lines and add copious documentation so you can keep understanding the expression in the future if this is something that needs to remain maintainable though.
(edited after realising the second openb reference was a conditional expression, and to properly translate the backreference).
I found the offending part but can't figure out what exactly is wrong without wrapping my mind around the whole thing.
r = re.compile(r'^(?:(?P<name>.*?)[\/\s._-]*)?(?P<openb>\[)?(?P<season>\d{1,2})[x\/](?P<episode>\d{1,2})(?:-(?:\kP<season>x)?(?P<endep>\d{1,2}))?
(?(P<openb>)\]) // this part here causes the error message
(?:[\s._-]*(?P<epname>[^\/]+?))?$')
The problem seems to be with the fact that group names in python must be valid python identifiers (check documentation). The parentheses seem to be the problem. Removing them gives
(?(P<openb>)\]) //with parentheses
(?P<openb>\]) //without parentheses
redefinition of group name 'openb' as group 6; was group 2
Those regexps are the product of a sick an twisted mind... :-)
Anyway, (?()) are conditions in both Python and Perl, and the perl syntax above looks like it should be the same as the Python syntax, i.e., it evaluates as true of the group named exists.
Where to start looking? The documentation for the modules are here:
http://docs.python.org/library/re.html
http://www.perl.com/doc/manual/html/pod/perlre.html
I may be wrong but you tried to get the backreference using :
(?:\k<season>x)
Isn't the syntax \g<name> in Python ?

Categories