Formatting error reporting - python-2.7

I am logging all errors to a file, since there is no other way to see them properly in my case, especially in prod environment. Like this:
sys.stderr = open('py/log/my_logfile.error.log', 'a')
I am getting something similar to this:
Traceback (most recent call last):
File "my_awesome_file.py", line 50, in <module>
revision = session.Query()
AttributeError: 'Awesome' object has no attribute 'SomeSortOfAttribute'
Traceback (most recent call last):
File "my_awesome_file.py", line 50, in <module>
revision = session.Query()
AttributeError: 'Awesome' object has no attribute 'SomeSortOfAttribute'
It's two errors here (well, same error logged twice). I'd like to have if formatted a bit nicer (i.e. additional newline in between errors), and add a datetime if possible. Can I do it using this method of error logging?

After a little bit of reading Python manuals, it seems the solution is rather easy - instead of directly using file open() as a stream for stderr, I just have to use a custom stream. It's so painfully obvious it puzzles me why I didn't come up with it immediately. Well, it was Friday evening after all.
A very basic version would be:
import time
class LogStream(object):
def write(self, text):
f = open('py/log/my.custom.error.log', 'a')
f.write(time.strftime("%H:%M:%S ") + text + "\r\n")
f.close()
And then
sys.stderr = LogStream()
Result:
12:03:05 Traceback (most recent call last):
12:03:05 File "py/stuff.py", line 38, in <module>
12:03:05
12:03:05 raise Exception("just some test")
12:03:05 Exception
12:03:05 :
12:03:05 just some test
12:03:05
I might want to customize it a bit more but it's good enough already.

Related

Why isdigit is working but isdecimal is not for a simple age code

This is the part of code I am talking about:
while True:
print 'What is your age(only numeric):'
age = raw_input()
if age.isdigit():
break
print 'Please try again. We take only numeric value.'
When I replace isdigit with isdecimal, I get this error no matter what value i enter.
Traceback (most recent call last):
File "test.py", line 4, in <module>
if age.isdecimal():
AttributeError: 'str' object has no attribute 'isdecimal'
Although it runs fine with isdigit.
Also, when I replace raw_input with input, it give this error.
Traceback (most recent call last):
File "test.py", line 4, in <module>
if age.isdigit():
AttributeError: 'int' object has no attribute 'isdigit'
Am I doing something wrong which I am not able to catch? I am new to python and did my research about isdigit, is decimal, input and raw_input before putting down question here. It may be very minute error but I am not sure what is it.
For the first part:
In Python 2, isdecimal is a method of the unicode class, not of str (i.e. bytes). Hence:
>>> '3.2'.isdecimal()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'isdecimal'
>>> u'3.2'.isdecimal()
For the second part, input tries to guess what kind of input it gets, and will properly cast "1" into an int, while raw_input will always return the raw string. Since isdigit is a method defined in the str class, you get the error.

I get an Error 6 with Asciimatics and Python

I am learning how to use asciimatics with Python.
When I try to run the following code:
from asciimatics.screen import Screen
from time import sleep
def demo(screen):
screen.print_at('Hello world!', 0, 0)
screen.refresh()
sleep(10)
Screen.wrapper(demo)
I get this error:
Traceback (most recent call last):
File "C:\Users\Patrick\Pictures\Python\Westhope\2.0\test.py", line 20, in <module>
Screen.wrapper(demo)
File "C:\Python27\lib\asciimatics\screen.py", line 1336, in wrapper
unicode_aware=unicode_aware)
File "C:\Python27\lib\asciimatics\screen.py", line 1245, in open
None))
error: (6, 'CreateFile', 'The handle is invalid.')
The short answer is that you are not running in a proper console/terminal window and you need to run inside the standard Windows command prompt instead.
See https://asciimatics.readthedocs.io/en/latest/troubleshooting.html#i-can-t-run-it-inside-pycharm-or-other-ides for more details.

Django tests failing when run with all test cases

I have a problem with tests. When I run some tests I launch separately, they pass. When all together then fail.
#mock.patch(
'apps.abstract.validators.years_range_is_not_future', new=fake_years_range_is_not_future
)
def test_create_building_with_validation_of_foundation_period(self):
self.c.login(username=self.user.username, password='111')
response = self.c.post(
'/en/api/buildings/',
data={
'name': "New Building",
'foundation_period': {
'lower': MIN_INT_VALUE,
'upper': MAX_INT_VALUE
},
'stream': {
'uuid': s_uuid(self.stream)
}
}
)
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
I read about this problem here
why would a django test fail only when the full test suite is run?
and tried to patch the validator in the serializer file as shown here
#mock.patch(
'apps.buildings.api.serializers.years_range_is_not_future', new=fake_years_range_is_not_future
)
def test_create_building_with_validation_of_foundation_period(self):
..............................................................
but then I get an incomprehensible for me exception
Error
Traceback (most recent call last):
File "/usr/lib/python3.5/unittest/mock.py", line 1049, in _dot_lookup
return getattr(thing, comp)
AttributeError: module 'apps.buildings.api' has no attribute 'serializers'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib/python3.5/unittest/mock.py", line 1149, in patched
arg = patching.__enter__()
File "/usr/lib/python3.5/unittest/mock.py", line 1205, in __enter__
self.target = self.getter()
File "/usr/lib/python3.5/unittest/mock.py", line 1375, in <lambda>
getter = lambda: _importer(target)
File "/usr/lib/python3.5/unittest/mock.py", line 1062, in _importer
thing = _dot_lookup(thing, comp, import_path)
File "/usr/lib/python3.5/unittest/mock.py", line 1051, in _dot_lookup
__import__(import_path)
File "/home/env/project/apps/buildings/api/serializers.py", line 12, in <module>
from apps.communities.api.serializers import CommunityBriefSerializer
File "/home/env/project/apps/communities/api/serializers.py", line 297, in <module>
class CommunityOfficialRequestBuildingSerializer(BaseCommunityOfficialRequestSerializer):
File "/home/rp/env/project/apps/communities/api/serializers.py", line 299, in CommunityOfficialRequestBuildingSerializer
from apps.buildings.api.serializers import BuildingBriefSerializer
ImportError: cannot import name 'BuildingBriefSerializer'
help please understand what I'm doing wrong
project structure (__init__.py files not listed)
project
|__apps
|__communities
| |_api
| |_serializers.py
|
|__buildings
| |_api
| | |_serializers.py
| |
| |_tests
| |_test.py
|
|_abstract
|_validators.py
Seeing this,
Traceback (most recent call last):
File "/home/rp/env/project/apps/communities/api/serializers.py", line 299, in CommunityOfficialRequestBuildingSerializer
from apps.buildings.api.serializers import BuildingBriefSerializer
suggests that your import statement is inside a class or a def or some other statement.
Maybe the import statement is executed after you mocked apps.buildings.api.serializers. If you move this import to the top of the file, then BuildingBriefSerializer will probably become available before apps.buildings.api.serializers is mocked, and your tests will pass.
This would also explain why the tests run, when you run them individually.

Debug django tests

I see that TestCase has a method Debug(), but I can't find any example on how to implement it. As far as I've tried, nothing works.
Can anyone provide some code as to how to use it?
debugunit.py
from unittest import TestCase
class MyTest(TestCase):
def test1(self):
print 'before'
self.assertEquals(2+2, 5)
print 'after'
run
python -i debugunit.py
To run a test interactively, create a TestCase instance, giving it the test name as a parameter. To run it, call the resulting object.
>>> print MyTest('test1')()
before
None
The "2+2!=5" exception is consumed by the unittest machinery. To get the set to run (with setUp and tearDown, etc), run the debug() method:
>>> MyTest('test1').debug()
before
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/unittest/case.py", line 400, in debug
getattr(self, self._testMethodName)()
File "debugunit.py", line 6, in test1
self.assertEquals(2+2, 5)
File "/usr/lib/python2.7/unittest/case.py", line 515, in assertEqual
assertion_func(first, second, msg=msg)
File "/usr/lib/python2.7/unittest/case.py", line 508, in _baseAssertEqual
raise self.failureException(msg)
AssertionError: 4 != 5

os.system in a loop

For each item in a list, I am modifying a file and then I want to run the python script, "ncall.py", which imports the modified file called, "new_basketparams.txt". I also want to make sure ncall.py completes its process before recalling it, but that is perhaps another topic. I am working on an ubuntu linux machine with python 2.7.
Here's the issue: My code seems to call ncall.py infinite times, stuck inside of the loop. I cannot even use a keyboard shortcut to kill the process and must close the window to kill the process. Here is my code and if anyone can help explain a solution, or guide me, that would be greatly appreciated:
import os
import re
datelist=['2014-05-16','2014-05-15','2014-05-14','2014-05-13','2014-05-12']
for date in datelist:
f=open('basketparams.txt')
g=open('new_basketparams.txt','w')
for line in f:
if "Start" in line:
line=line.split(";")
line[2]=re.sub('\d\d\d\d-\d\d-\d\d',date,line[2])
line=';'.join(line)
elif "End" in line:
line=line.split(";")
line[2]=re.sub('\d\d\d\d-\d\d-\d\d',date,line[2])
line=';'.join(line)
else:
pass
g.write(line)
os.system("python ncall.py")
Here are some diagnostics. The import MySQL error is strange because ncall works when called by itself from the terminal
'import site' failed; use -v for traceback
Traceback (most recent call last):
File "ncall.py", line 1, in <module>
import MySQLdb
ImportError: No module named MySQLdb
[]
calling ncall.py no. 1 2014-05-21 07:30:46.400011
new_basketparams.txt
Traceback (most recent call last):
File "ncall.py", line 15, in <module>
Price_Min=display.input[2]
IndexError: list index out of range
[]
calling ncall.py no. 1 2014-05-21 07:30:46.352573
new_basketparams.txt
Traceback (most recent call last):
File "ncall.py", line 15, in <module>
Price_Min=display.input[2]
IndexError: list index out of range
[]
calling ncall.py no. 1 2014-05-21 07:30:46.305043
new_basketparams.txt
Traceback (most recent call last):
File "ncall.py", line 15, in <module>
Price_Min=display.input[2]
IndexError: list index out of range
Now I am including a portion of code from ncall.py as well as display.py:
#ncall.py
import MySQLdb
import csv
import display
import time
from display import fileinput
from datetime import datetime, date, time, timedelta
import datelist
now0=datetime.now()
print fileinput
Start_Datetime='%s 14:00:00'%(datelist.date)
End_Datetime='%s 14:59:59'%(datelist.date)
Price_Min=display.input[2]
Price_Max=display.input[3]
Under=display.input[4]
#display.py
fileinput='new_basketparams.txt'
f=open(fileinput)
input=[]
for line in f:
print 'reading line in fileinput in display.py\'s loop: ', line
try:
line=line.split(';')
parameter=line[0]
Input=line[2]
x=Input.split('\r')
input.append(x[0])
except :
continue