Due to this, I need to use python memoryview.cast('I') to access a FPGA avoiding double read/write strobe. No panic, you wont need an FPGA to answer the question below...
So here comes a python sample which fails ('testfile' can be any file here -just longer than 20 bytes-, but for me, eventually it will be a IO mapped FPGA HW):
#!/usr/bin/python
import struct
import mmap
with open('testfile', "r+b") as f:
mm=memoryview(mmap.mmap(f.fileno(), 20)).cast('I')
# now try to assign the 2 first U32 of the file new values 1 and 2
# mm[0]=1; mm[1]=2 would work, but the following fails:
mm[0:1]=memoryview(struct.pack('II',1,2)).cast('I') #assignement error
The error is:
./test.py
Traceback (most recent call last):
File "./test.py", line 8, in <module>
mm[0:1]=memoryview(struct.pack('II',1,2)).cast('I')
ValueError: memoryview assignment: lvalue and rvalue have different structures
I don't undestand the error... what "different structures" are we talking about??
How can I rewrite the right hand-side of the assignment expression so it works??
Changing the left-hand-side will fail for the FPGA... as it seems anything else generates wrong signal towards the hardware...
More generally, how should I rework my array of 32 bit integers to fit the left-hand-side of the assignment...?
Yes #Monica is right: The error was simpler than I though. The slice on the left hand side is wrong indeed.
When I try to use print without parentheses on a simple name in Python 3.4 I get:
>>> print max
Traceback (most recent call last):
...
File "<interactive input>", line 1
print max
^
SyntaxError: Missing parentheses in call to 'print'
Ok, now I get it, I just forgot to port my Python 2 code.
But now when I try to print the result of a function:
>>> print max([1,2])
Traceback (most recent call last):
...
print max([1,2])
^
SyntaxError: invalid syntax
Or:
print max.__call__(23)
^
SyntaxError: invalid syntax
(Note that the cursor is pointing to the character before the first dot in that case.)
The message is different (and slightly misleading, since the marker is below the max function).
Why isn't Python able to detect the problem earlier?
Note: This question was inspired by the confusion around this question: Pandas read.csv syntax error, where a few Python experts missed the real issue because of the misleading error message.
Looking at the source code for exceptions.c, right above _set_legacy_print_statement_msg there's this nice block comment:
/* To help with migration from Python 2, SyntaxError.__init__ applies some
* heuristics to try to report a more meaningful exception when print and
* exec are used like statements.
*
* The heuristics are currently expected to detect the following cases:
* - top level statement
* - statement in a nested suite
* - trailing section of a one line complex statement
*
* They're currently known not to trigger:
* - after a semi-colon
*
* The error message can be a bit odd in cases where the "arguments" are
* completely illegal syntactically, but that isn't worth the hassle of
* fixing.
*
* We also can't do anything about cases that are legal Python 3 syntax
* but mean something entirely different from what they did in Python 2
* (omitting the arguments entirely, printing items preceded by a unary plus
* or minus, using the stream redirection syntax).
*/
So there's some interesting info. In addition, in the SyntaxError_init method in the same file, we can see
/*
* Issue #21669: Custom error for 'print' & 'exec' as statements
*
* Only applies to SyntaxError instances, not to subclasses such
* as TabError or IndentationError (see issue #31161)
*/
if ((PyObject*)Py_TYPE(self) == PyExc_SyntaxError &&
self->text && PyUnicode_Check(self->text) &&
_report_missing_parentheses(self) < 0) {
return -1;
}
Note also that the above references issue #21669 on the python bugtracker with some discussion between the author and Guido about how to go about this. So we follow the rabbit (that is, _report_missing_parentheses) which is at the very bottom of the file, and see...
legacy_check_result = _check_for_legacy_statements(self, 0);
However, there are some cases where this is bypassed and the normal SyntaxError message is printed, see MSeifert's answer for more about that. If we go one function up to _check_for_legacy_statements we finally see the actual check for legacy print statements.
/* Check for legacy print statements */
if (print_prefix == NULL) {
print_prefix = PyUnicode_InternFromString("print ");
if (print_prefix == NULL) {
return -1;
}
}
if (PyUnicode_Tailmatch(self->text, print_prefix,
start, text_len, -1)) {
return _set_legacy_print_statement_msg(self, start);
}
So, to answer the question: "Why isn't Python able to detect the problem earlier?", I would say the problem with parentheses isn't what is detected; it is actually parsed after the syntax error. It's a syntax error the whole time, but the actual minor piece about parentheses is caught afterwards just to give an additional hint.
The special exception message for print used as statement instead of as function is actually implemented as a special case.
Roughly speaking when a SyntaxError is created it calls a special function that checks for a print statement based on the line the exception refers to.
However, the first test in this function (the one responsible for the "Missing parenthesis" error message) is if there is any opening parenthesis in the line. I copied the source code for that function (CPython 3.6.4) and I marked the relevant lines with "arrows":
static int
_report_missing_parentheses(PySyntaxErrorObject *self)
{
Py_UCS4 left_paren = 40;
Py_ssize_t left_paren_index;
Py_ssize_t text_len = PyUnicode_GET_LENGTH(self->text);
int legacy_check_result = 0;
/* Skip entirely if there is an opening parenthesis <---------------------------- */
left_paren_index = PyUnicode_FindChar(self->text, left_paren,
0, text_len, 1);
if (left_paren_index < -1) {
return -1;
}
if (left_paren_index != -1) {
/* Use default error message for any line with an opening parenthesis <------------ */
return 0;
}
/* Handle the simple statement case */
legacy_check_result = _check_for_legacy_statements(self, 0);
if (legacy_check_result < 0) {
return -1;
}
if (legacy_check_result == 0) {
/* Handle the one-line complex statement case */
Py_UCS4 colon = 58;
Py_ssize_t colon_index;
colon_index = PyUnicode_FindChar(self->text, colon,
0, text_len, 1);
if (colon_index < -1) {
return -1;
}
if (colon_index >= 0 && colon_index < text_len) {
/* Check again, starting from just after the colon */
if (_check_for_legacy_statements(self, colon_index+1) < 0) {
return -1;
}
}
}
return 0;
}
That means it won't trigger the "Missing parenthesis" message if there is any opening parenthesis in the line. That leads to the general SyntaxError message even if the opening parenthesis is in a comment:
print 10 # what(
print 10 # what(
^
SyntaxError: invalid syntax
Note that the cursor position for two names/variables separated by a white space is always the end of the second name:
>>> 10 100
10 100
^
SyntaxError: invalid syntax
>>> name1 name2
name1 name2
^
SyntaxError: invalid syntax
>>> name1 name2([1, 2])
name1 name2([1, 2])
^
SyntaxError: invalid syntax
So it is no wonder the cursor points to the x of max, because it's the last character in the second name. Everything that follows the second name (like ., (, [, ...) is ignored, because Python already found a SyntaxError, and it doesn't need to go further, because nothing could make it valid syntax.
Maybe I'm not understanding something, but I don't see why Python should point out the error earlier. print is a regular function, that is a variable referencing a function, so these are all valid statements:
print(10)
print, max, 2
str(print)
print.__doc__
[print] + ['a', 'b']
{print: 2}
As I understand it, the parser needs to read the next full token after print (max in this case) in order to determine whether there is a syntax error. It cannot just say "fail if there is no open parenthesis", because there are a number of different tokens that may go after print depending on the current context.
I don't think there is a case where print may be directly followed by another identifier or a literal, so you could argue that as soon as there is one letter, a number or quotes you should stop, but that would be mixing the parser's and the lexer's job.
in additions to those excellent answers, without even looking at the source code, we could have guessed that the print special error message was a kludge:
so:
print dfjdkf
^
SyntaxError: Missing parentheses in call to 'print'
but:
>>> a = print
>>> a dsds
Traceback (most recent call last):
File "<interactive input>", line 1
a dsds
^
SyntaxError: invalid syntax
even if a == print but at that stage, it isn't evaluated yet, so you get the generic invalid syntax message instead of the hacked print syntax message, which proves that there's a kludge when the first token is print.
another proof if needed:
>>> print = None
>>> print a
Traceback (most recent call last):
File "C:\Python34\lib\code.py", line 63, in runsource
print a
^
SyntaxError: Missing parentheses in call to 'print'
in that case print == None, but the specific message still appears.
I've been trying out various algorithms for my thesis. And now i'm currently focusing in template matching (where the main focus in matching would be the edge). Then I found out about chamfer matching. I'm torn between coding it myself, or using available implementations (which is better). Then I found out about a cpp implementation of the said algorithm. However, I'm encountering weird error. ↓
OpenCV Error: Assertion failed (img.type() == CV_8UC1 && templ.type() == CV_8UC1)
in chamerMatching, file /home/pyimagesearch/Downloads/opencv-2.4.8/modules/contrib/src/chamfermatching.cpp, line 1370
Traceback (most recent call last):
File "template.py", line 12, in <module> cv2.chamerMatching(template1, queryFrame, 1, 1) cv2.error:
/home/pyimagesearch/Downloads/opencv-2.4.8/modules/contrib/src/chamfermatching.cpp:1370:
error: (-215) img.type() == CV_8UC1 && templ.type() == CV_8UC1 in function chamerMatching
i tried to locate the directory /home/pyimagesearch/Downloads/opencv-2.4.8/modules/contrib/src/chamfermatching.cpp (so as to inspect whether i'm missing out on the parameter required for the function call), but to my surprise, there's no opencv-2.4.8 folder under my Downloads folder.
does anyone know what could be the main cause of the error?
Your answer would be much appreciated. :) thanks!
I think type function don't return value like cv8uc1 . It should return integer value. You can find list of integer value map which is returned by type function in following page http://ninghang.blogspot.com.tr/2012/11/list-of-mat-type-in-opencv.html?m=1. Could you change them and try again ?
I'm trying to call a dll function using ctypes and getting an error. How can I get more info of what is wrong with my call?
dll function header:
DLL_API BOOL WINAPI DDSSetFrequency(int index, double frequency, int* wavePointNum, int* TNum);
python code
from ctypes import *
hantek = cdll.LoadLibrary("E:\Programmer's Guide\DLL\DDS3X25Dll.dll")
print hantek.DDSSearch()
wavePointNum = c_int()
Tnum = c_int()
frequency = c_double(10000000.0)
index = c_int32(1)
hantek.DDSSetFrequency(index,frequency,byref(wavePointNum),byref(Tnum))
1
Traceback (most recent call last):
File "3x25.py", line 17, in <module>
hantek.DDSSetFrequency(index,frequency,byref(wavePointNum),byref(Tnum))
ValueError: Procedure called with not enough arguments (20 bytes missing) or wro
ng calling convention
You are probably not still working on this project, but in case you are (and for posterity's sake), I am providing a link to a python wrapper I've written for the HT1025G that demonstrates a working interface. The set_frequency method is a bit persnickety, and I've found better luck with (the undocumented) set_divisor method.
I am getting the error:
Warning: invalid value encountered in log
From Python and I believe the error is thrown by numpy (using version 1.5.0). However, since I am calling the "log" function in several places, I'm not sure where the error is coming from. Is there a way to get numpy to print the line number that generated this error?
I assume the warning is caused by taking the log of a number that is small enough to be rounded to 0 or smaller (negative). Is that right? What is the usual origin of these warnings?
Putting np.seterr(invalid='raise') in your code (before the errant log call)
will cause numpy to raise an exception instead of issuing a warning.
That will give you a traceback error message and tell you the line Python was executing when the error occurred.
If you have access to the numpy source, you should be able to find the line that prints that warning (using grep, etc) and edit the corresponding file to force an error (using an assertion, for example) when an invalid value is passed. That will give you a stack trace pointing to the place in your code that called log with the improper value.
I had a brief look in my numpy source, and couldn't find anything that matches the warning you described though (my version of numpy is older than yours, though).
>>> import numpy
>>> numpy.log(0)
-inf
>>> numpy.__version__
'1.3.0'
Is it possible that you're calling some other log function that isn't in numpy? For example, here is one that actually throws an exception when given invalid input.
>>> import math
>>> math.log(0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: math domain error