Python: Assert a UserWarning - python

I created my own python script script.py in which I define my own class (e.g. myclass). The class reads a csv file as a dataframe. One of the checks that I established is for making sure that a specific column exists in the dataset. The check is:
if ("column" not in self.df.columns): warnings.warn("column is not available in the input file.")
This actually works fine and when the "column" is not included in the dataset, the warning error is produced:
UserWarning: column is not available in the input file.
if ("column" not in self.df.columns): warnings.warn("column is not available in the input file.")
I am trying to verify/assert the issue of the warning message by running the following unit test:
import script
...
...
...
def test_if_error_is_issued ():
with pytest.raises(UserWarning) as warn:
script.myclass(path)
I think that the latter code chunk is not correct as I keep receiving the following error message ( path actually leads to a csv without the "column"):
E Failed: DID NOT RAISE <class 'UserWarning'>

MrBean Bremen answered this question.
The solution is to change pytest.raises to pytest.warns.

Related

How to use a Python class file in another script (in Matlab)

I am new to python and mainly use Matlab. I found some Python code on Github (https://github.com/simonmb/fragmentation_algorithm) that I want to run in Matlab, but I can't even manage to write a function in Python to run the code with any input. When I try to run the function I wrote (called 'RunFrag.py') in the Console in PyCharm, I only get the following error: NameError: name 'RunFrag' is not defined, even though the script is in the same folder. The file from Github ('fragmenter.py') defines a class and has the line __name__ == '__main__' and I have no idea how to deal with this, in Matlab classes occur rather rarely.
Can anyone help me with creating a function where I can just enter a SMILES molecule as input and get the fragmentation out?
Thanks in advance.
Here is the Code from the RunFrag function I wrote (the additionally needed fragmenter.py file can be found at the github link):
def RunFrag(smiles):
from .fragmenter import fragmenter
fragmentation_scheme = {
'CH2' : '[CH2]',
'OH' : '[OH]',
'CH3' : '[CH3]',
'CH2-CH2' : '[CH2][CH2]'
}
fragmentation_scheme_order1 = ['CH2-CH2', 'CH3', 'CH2', 'OH']
frg = fragmenter(fragmentation_scheme, fragmentation_scheme_order=fragmentation_scheme_order1, algorithm='simple')
fragmentation, success, fragmentation_matches = frg.fragment(smiles)
return smiles, fragmentation, success

Within a python script, check syntactic correctness of C code in str format

Necessarily within a python program and given an str variable that contains C code, I want to check fast if this code is syntactically correct, or not. Essentially, I only need to pass it through the compiler's front end.
My current implementation uses a temp file to dump the string and calls a clang process with subprocess (non-working code below to illustrate my solution). This is very slow for my needs.
src = "int main(){printf("This is a C program\n"); return 0;}"
with open(temp_file, 'w') as f:
f.write(src)
cmd = ["clang", abs_path(f), flags]
subprocess.Popen(cmd)
## etc..
After looking around, I found out about clang.cindex module (pip clang), which I tried out. After reading a bit the main module, lines 2763-2837 (specifically line 2828) led me to the conclusion that the following code snippet will do what I need:
import clang.cindex
......
try:
unit = clang.cindex.TranslationUnit.from_source(temp_code_file, ##args, etc.)
print("Compiled!")
except clang.cindex.TranslationUnitLoadError:
print("Did not compile!")
However, it seems that even if the source file contains obvious syntactic errors, an exception is not raised. Anyone knows what am I missing to make this work ?
On a general context, any suggestions on how to do this task as fast as possible would be more than welcome. Even with clang.cindex, I cannot get away from writing my string-represented code to a temp file, which may be an additional overhead. Writing a python parser could solve this but is an overkill at the moment, no matter how much I need speed.
The compilation itself succeeds even if the file has syntax errors. Consider the following example:
import clang.cindex
with open('broken.c', 'w') as f:
f.write('foo bar baz')
unit = clang.cindex.TranslationUnit.from_source('broken.c')
for d in unit.diagnostics:
print(d.severity, d)
Run it and you will get
3 broken.c:1:1: error: unknown type name 'foo'
3 broken.c:1:8: error: expected ';' after top level declarator
The severity member of is an int, with the value from the enum CXDiagnosticSeverity with values
CXDiagnostic_Ignored = 0
CXDiagnostic_Note = 1
CXDiagnostic_Warning = 2
CXDiagnostic_Error = 3
CXDiagnostic_Fatal = 4

Robot Framework: How to merge old/new statuses using rebot --merge and keep the only one?

I'm using rebot tool to merge outputs after re-execution of failed tests.
robot --output original.xml /path/to/dir/.
robot --rerunfailed original.xml --output rerun.xml /path/to/dir/.
rebot -o machine1.xml -l machine1.html --merge original.xml rerun.xml
The same action is provided on few test machines.
Test suite is identical and is executed against each VM. All VMs are considered as identical, however, they are not stable and I receive different results on each machine.
I want to merge all results from all machines and retrieve the maximum number of Passed tests, to understand whether the test is REALLY failing or it's just unstable environment and test is OK by itself.
Other words, if test passed at least on 1 machine, but failed on other 3 machines, it needs to be considered as Passed in the final report.
However I receive False for such case.
Is it possible to change the behavior somehow?
Example from the final report:
Status: FAIL (critical)
Message: Re-executed test has been merged.
New status: FAIL
New message: Re-executed test has been merged.
New status: FAIL
New message: IndexError: Given index 0 is out of the range 0--1.
Old status: FAIL
Old message: IndexError: Given index 0 is out of the range 0--1.
Old status: PASS
Old message: Re-executed test has been merged.
New status: PASS
New message:
Old status: PASS
Old message: Re-executed test has been merged.
New status: PASS
New message:
Old status: PASS
Old message:
Resolved by using simple script for prerebotmodifier written by myself. Maybe it will be helpful for somebody else.
So, I created TestStatusChecker.py which helps to merge reports with the following logic: test status will be failed ONLY if it was failing in ALL reports.
from robot.api import SuiteVisitor
class TestStatusChecker(SuiteVisitor):
def __init__(self, *args):
pass
def visit_test(self, test):
if 'PASS' in test.message and 'Re-executed test has been merged' in test.message:
test.status = 'PASS'
test.message = 'Test passed because it passed at least once.'
CLI command for merging the results:
rebot -l final_log.html --prerebotmodifier TestStatusChecker.py --merge 1.xml 2.xml 3.xml 4.xml
report

RuntimeError passing a yaml profile to Essentia MusicExtractor

I am trying to generate a feature set with the Essentia MusicExtractor from a yaml profile as described in the documentation here and here via python.
My code snippet:
from essentia.standard import MusicExtractor
profile = "some_profile.yaml"
audio = "some_audio.mp3"
features, frames = MusicExtractor(profile=profile)(audio)
My yaml profile:
This produces the folling error:
RuntimeError:
Error while configuring MusicExtractor:
Pool: Cannot set/add/merge value to the pool under the name 'rhythm.stats'
because that name already exists but contains a different data type than value.
It does not really look that i am doing something wrong.
I ran into the same problem and fixed it this way:
Downloaded a sample profile from the essentia repos examples.
Ran the profile.
Commented out the conflicting lines after each run, which are just a few. Basically the stats and statsMFCC lines.
From this I could derive a working profile.

Python win32com CallNotImplementedError instead of AccessDenied?

This code:
import os
from win32com.shell import shell, shellcon
tempFile = os.path.join(os.path.abspath(os.path.curdir), u'_tempfile.tmp')
# print tempFile
dest = os.path.join('C:\Program Files', '_tempfile.tmp')
with open(tempFile, 'wb'): pass # create the file
try: # to move it into C:\Program Files
result, aborted = shell.SHFileOperation(
(None, # parent window
shellcon.FO_MOVE, tempFile, dest,
# 0,
shellcon.FOF_SILENT, # replace this with 0 to get a UAC prompt
None, None))
print result, aborted
except: # no exception raised
import traceback
traceback.print_exc()
Prints 120 False - 120 being CallNotImplementedError. If the flags are set to 0 then you get a UAC prompt as expected. Now why is not the result 5 (AccessDeniedError) ? Is something not implemented indeed or is it a bug or what do I not get ?
Needless to say that this was hard to debug - I was expecting an access denied and I had to look very closely to see what was wrong.
You're misreading the error code. SHFileOperation uses its own set of error codes separate from the system error codes; in this case, 0x78/120 is:
DE_ACCESSDENIEDSRC: Security settings denied access to the source.
That doesn't seem like it's the likely error (the destination is the problem), but this function is deprecated (replaced in Vista by IFileOperation) and while it still exists in Vista+, they may not have been particularly careful about returning entirely accurate error codes for situations (like UAC) that didn't exist pre-Vista.
Per the docs:
These are pre-Win32 error codes and are no longer supported or defined in any public header file. To use them, you must either define them yourself or compare against the numerical value.
These error codes are subject to change and have historically done so.
These values are provided only as an aid in debugging. They should not be regarded as definitive.

Categories