Check error log in NVDA - python

How can I check errors in my code using NVDA error log? I've created an addon, which seemingly doesn't works due to some error. How can I debug my code using error log or any other method possible?
The error I'm facing is in the following code:
import globalPluginHandler
import ui
import versionInfo
from NVDAObjects.window.scintilla import Scintilla
class GlobalPlugin(globalPluginHandler.GlobalPlugin):
def _messag(self, gesture):
ui.message("notepad++ opened") # speak hello when notepad++ is the current screen
def chooseNVDAObjectOverlayClasses(self, obj, clsList):
if obj.windowClassName == u'Scintilla' and obj.windowControlID == 0:
clsList.insert(0, self._messag)

I don't know anything about NVDA, but when python programs fail, they do it by raising an exception. You could perhaps include a mechanism to catch these exceptions and send them to a file. For example let's take a plugin from the NVDA developer's guide
--- start ---
# Version announcement plugin for NVDA
# Developer guide example 2
import globalPluginHandler
import ui
import versionInfo
class GlobalPlugin(globalPluginHandler.GlobalPlugin):
#MY_EXCEPTION_CATCHER
def script_announceNVDAVersion(self, gesture):
ui.message(versionInfo.version)
__gestures={
"kb:NVDA+shift+v": "announceNVDAVersion",
}
--- end ---
I added a decorator to the code that catches the exceptions that may occur and displays them in an html file that can be displayed in browser for example
import functools
import cgitb
import sys
def MY_EXCEPTION_CATCHER(func):
#functools.wraps(func)
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception:
with open('exception.html', 'w') as outfile:
outfile.write(cgitb.html(sys.exc_info())
raise
return wrapper
I hope it helps.

Related

Python remove logging file after running tests

I am testing the logger's functionality and it requires me to create a log file, but at the end I want to remove it so I tried to os.remove in the tearDownClass
#classmethod
def tearDownClass(cls) -> None:
log = logging.getLogger('client_logger')
try:
log.removeHandler(log.handlers.pop())
except:
pass
os.remove('client_logger.log')
I read that the RotatingFileHandler is the cause of it and once I remove it the handler list is empty, but it still gives me PermissionError: [WinError 32].
Log files work like any other ordinary files. It must be opened and closed.
The same goes for the log files. The log handlers opens a file to write into.
This means it before the file can be removed it should be disconnected to the log handler.
Example with Django TestCase:
import os
import logging
from django.test import TestCase
_logger = logging.getLogger("logger_name")
class CustomTestCase(TestCase):
def setUp(self) -> None:
... # stuff
def test_more_stuff(self) -> None:
... # more stuff
def tearDown(self) -> None:
# First close logger file before removing.
_logger.handlers[0].close() # <FileHandler D:\path\to\logfile\test.log (DEBUG)>
if os.path.exists("test.log"):
os.remove("test.log")
The following StackOverflow page helped me find a solution.
Reference: python does not release filehandles to logfile

Python Debug Fail - execution ends

I'm debugging Python with Visual Studio 2015 (Python Tools extension).
I'm very new to Python and strangely when i debug the bellow code, it runs to line 18, then line 19, then line 18 again where it exits unceremoniously. Doesn't hit my catch block, doesn't hit line 20 or 21. No error message. Anyone know what might be causing this?
The unit test is testing a common google api functionality found on Git Hub here.
My Code:
import unittest
import sys
import os
import exceptions
from _multiprocessing import flags
sys.path.insert(0, "C:\Users\Jamie.Marshall\Documents\Visual Studio 2015\Projects\GetDCMPlalyStationData\DCMPSDataQuery")
try:
from dfareporting_utils import get_arguments
except ImportError:
print(ImportError.message)
print('No Import')
try:
#Line18
class Test_dfareporting_utility_test(unittest.TestCase):
#Line19
def test_A(self):
flags = get_arguments(sys.argv, __doc__, parents=[argparser])
self.assertEqual(flags[0], "")
except Exception as ex:
print(ex.message)
print(ex.source)
if __name__ == '__main__':
unittest.main()
When a class is initialized, only the signature lines of the class, the code at the top level of the class and signature lines the methods inside are executed. The code in the methods is executed only when the methods are called. An example:
E class MyClass:
|
E my_class_attribute = 1
|
E def my_method(self, a):
N b = a + 1
N return b
E = excuted; N = not executed
Your try around the class will have no effect unless an error is raised on the class or the def line.
At the result your try around the class will have no effect unless an error is raised in one of that lines.
To catch an exception in a test put the try / except inside the method. But you should actually have a defined state in your test and the error should be expected or not present, so it might be the best to expect an error and test for it with with self.assertRaises(YourErrorType):

Pythonic way to handle import errors

I am using a custom logging module in my project. If it is not available, I'd like to substitute it with a dummy instead of raising an ImportError.
Here's the code which currently does that:
try:
import logger
except ImportError:
print 'Couldn\'t load logger'
class DummyLogger(object):
def __init__(self):
pass
def log(self, image):
pass
logger = DummyLogger()
I don't think it's an elegant solution. It works, sure, but it ain't nice. Is there a better way?
I would put the dummy implementation into a separate module, called dummy_loggger, and write:
try:
import logger
except ImportError:
import dummy_logger as logger
I've done this in the past with JSON parsers:
try:
import ujson as json # very fast but might not be available in some cases
except ImportError:
import json
You can make it more concise quite easily:
try:
import logger
except ImportError:
print 'Couldn\'t load logger'
class logger(object):
#classmethod
def log(cls, image):
pass
Note that, even in your current version, the empty __init__ should be removed -- it adds no value.

Unable to send notification to errbit

I am using Python's https://github.com/pulseenergy/airbrakepy Which is a synonym to Ruby's Airbrake gem. Now, i have installed https://github.com/errbit/errbit at my end. Now, i want to send all error notices to errbit.
I have something similar to,
import logging
import ConfigParser
import os
import time
from airbrakepy.logging.handlers import AirbrakeHandler
def method_three():
raise StandardError('bam, pow')
def method_two():
method_three()
def method_one():
method_two()
if __name__=='__main__':
configFilePath = os.path.join(os.path.expanduser("~"), ".airbrakepy")
print(configFilePath)
parser = ConfigParser.SafeConfigParser()
parser.read(configFilePath)
api_key = parser.get("airbrake", "api_key")
url = parser.get("airbrake", "app_url")
logging.basicConfig(level=logging.ERROR)
logger = logging.getLogger("test-logger")
handler = AirbrakeHandler(api_key, environment='dev', component_name='integration-test', node_name='server', airbrake_url=url, use_ssl=False, timeout_in_ms=10000000)
logger.addHandler(handler)
logger.error("before exception")
try:
method_one()
except StandardError:
logger.error("test with exception", exc_info=True)
logger.error("test without exception", exc_info=False)
logger.error("after exception")
logging.shutdown()
I also have .airbrakepy which has api_key and errbit_url.
Anybody knows where am i making mistake.
I am not able to send notices to errbit through this method.
Please use https://github.com/aashish-pathak/airbrakepy
There is some issue with airbrakepy. I'll soon send pull request to main airbrakepy repo.

AttributeError - module is not available in threading.Thread

In Django I wrote a custom command, called update.
This command is continously called by a shell script and updates some values in the database. The updates are done in threads. I put the class doing all-threading related things in the same module as the custom command.
On my production server, when I try to run that shell script, I get an error when I try to access my models:
antennas = Antenna.objects.all()
The error is:
AttributeError: 'NoneType' object has no attribute 'objects'
As you can see, however, I did import app.models.Antenna in that file.
So to me, it seems as if the reference to the whole site is somehow "lost" inside the threading class.
site/app/management/commands/update.py
(I tried to remove all non-essential code here, as it would clutter everything, but I left the imports intact)
from django.core.management.base import NoArgsCommand, CommandError
from django.utils import timezone
from datetime import datetime, timedelta
from decimal import *
from django.conf import settings
from _geo import *
import random, time, sys, traceback, threading, Queue
from django.db import IntegrityError, connection
from app.models import Bike, Antenna
class Command(NoArgsCommand):
def handle_noargs(self, **options):
queue = Queue.Queue()
threadnum = 2
for bike in Bike.objects.filter(state__idle = False):
queue.put(bike)
for i in range(threadnum):
u = UpdateThread(queue)
u.setDaemon(True)
u.start()
queue.join()
return
class UpdateThread(threading.Thread):
def init(self, queue):
threading.Thread.init(self)
self.queue = queue
def run(self):
antennas = Antenna.objects.all()
while not self.queue.empty():
try:
[...]
except Exception:
traceback.print_exc(file=sys.stdout)
finally:
self.queue.task_done()
When I try to from app.models import Antenna inside the UpdateThread-class I get an error:
ImportError: No module named app.models
The site runs great on a webserver. No model-related problems there, only when I do anything inside a thread - all app.models-imports are failing.
Additionally, it seems to me as exactly the same configuration (I'm using git) does run on another machine, which runs the same operating system (debian wheezy, python 2.7.3rc2 & django 1.4.2).
Very probably I'm missing something obvious about threading here but I'm stuck for far too long now. Your help would be very much appreciated!
PS: I did check for circular imports - and those shouldn't happen anyway, as I can use my models in the other (management-)class, right?

Categories