statcktrace of classmethod not getting printed in python - python

There is a #classmethod in a class which is being called automatically when class is imported. I want to know the parameters being passed to that method. So I deliberately added a code to crash that function and to print the stacktrace. However, it is not printing who is calling this load method.
I actually want to know who is sending values of parameters (Specifically cuda_device)
#classmethod
def load(cls,
config: Params,
serialization_dir: str,
weights_file: str = None,
cuda_device: int = -1) -> 'Model':
who called me? #line added by me to crash and print stacktrace
File "/data/TFS/AI%20-%20Projects/MULTI_PROC/allen_ws/urls.py", line 19, in <module>
from allen_ws import ANLP_API_SB1
File "/data/TFS/AI%20-%20Projects/MULTI_PROC/allen_ws/ANLP_API_SB1.py", line 5, in <module>
from allennlp.predictors.predictor import Predictor
File "/anaconda3/envs/allennlpenv/lib/python3.6/site-packages/allennlp/predictors/__init__.py", line 9, in <module>
from allennlp.predictors.predictor import Predictor
File "/anaconda3/envs/allennlpenv/lib/python3.6/site-packages/allennlp/predictors/predictor.py", line 8, in <module>
from allennlp.models import Model
File "/anaconda3/envs/allennlpenv/lib/python3.6/site-packages/allennlp/models/__init__.py", line 6, in <module>
from allennlp.models.model import Model
File "/anaconda3/envs/allennlpenv/lib/python3.6/site-packages/allennlp/models/model.py", line 331
who called me?
In above stack trace models/__ init __ .py is calling the model.py line 331 (at line 331 I added "who called me"), the content of models/__ init __ .py at line 6 following is written:
from allennlp.models.model import Model
This is also not calling _load method with any parameters.
Suggestions please, how can I find who is passing cuda_device parameter value to load function?

You have introduced a syntax error into your code. That means your class cannot be imported, let alone run.
If you want to see a runtime stack trace then introduce a runtime error, not a syntax error.
a = 1 / 0
should do it.

Related

How to display definition of a class in Python

I was going through this question : How do I return the definition of a class in python?
But I am unable to display the class definition. I am getting the below error:
>>> class A:
... pass
...
>>> import inspect
>>> source_text = inspect.getsource(A)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\**\Python\Python36\lib\inspect.py", line 968, in getsource
lines, lnum = getsourcelines(object)
File "C:\Users\**\Python\Python36\lib\inspect.py", line 955, in getsourcelines
lines, lnum = findsource(object)
File "C:\Users\**\Python\Python36\lib\inspect.py", line 768, in findsource
file = getsourcefile(object)
File "C:\Users\**\Python\Python36\lib\inspect.py", line 684, in getsourcefile
filename = getfile(object)
File "C:\Users\**\Python\Python36\lib\inspect.py", line 654, in getfile
raise TypeError('{!r} is a built-in class'.format(object))
TypeError: <module '__main__' (<_frozen_importlib_external.SourceFileLoader object at 0x0000026A79293F60>)> is a built-in class
>>>
Can someone please advise what am I doing wrong here? Thanks.
The inspect.getsource() function only works if there is a text file available to load the source code.
You typed the definition of the class into the interactive interpreter, which doesn't keep the original source around when compiling that source into in-memory class and code objects.
Put your class definition into a module, import the module, and then use inspect.getsource().
inspect.getsource() works by first finding the module for a given object (for classes, by looking at the ClassObj.__module__ attribute for the module name, then getting the module via sys.modules[modulename]) then seeing if the module has a __file__ attribute from which a readable source file can be determined. If there is such a filename and it can be read, then the inspect module reads that file to then search for the class ClassName: line and giving you all lines from that point on with same or deeper indentation. The interactive interpreter executes everything in the __main__ module and there is no __file__ attribute for the interpreter, so any attempts at loading source code for objects defined there will simply fail.
If you just wanted to know what members the class defines, use dir() or help() on the object instead. You don't need to see the full source code for that information.

How to handle importing when testing Flask apps: AssertionError: View function mapping is overwriting an existing endpoint function

I am struggling trying to understand how to write tests in Flask.
I've inherited an app that already has a bunch of tests that hit routes like /login and test that the response is what's expected.
I have a substantially more complicated situation. I need to test a route/method that depending on the circumstances, hits an external api, figures out whether a path exists in the container the app itself is running in, starts a process that takes 10+ minutes to run on a different machine -- all manner of things. So I can't just hit the route and see if I got what I wanted; I need mocking and patching to mimic the effects of various external world states.
Right now I have a route defined like so in brain_db/views.py:
#app.route('/label_view/<int:scan_number>')
#login_required
def label_view(scan_number):
<so much complicated logic>
The first route defined in that same file, brain_db/views.py, is
#app.route('/surface_test')
def surface_test():
<some code>
Here is a simplified version of the file that's throwing the error:
import unittest
from mock import MagicMock, patch
from flask_brain_db.test_helpers import set_up, tear_down
from flask_brain_db.brain_db.models import Scan
from brain_db.views import label_view
class BrainDBTest(unittest.TestCase):
def setUp(self):
app, db = set_up()
scan = Scan(1, '000001', '000001_MR1', 'scan.nii.gz', scan_number=1)
db.session.add(scan)
scan = Scan.query.filter(Scan.scan_number == 1).first()
db.session.commit()
def tearDown(self):
tear_down()
def mock_volume_views_setup(self)
scan = Scan.query.filter(Scan.scan_number == 1).first()
container_file_path = '/path/to/file/in/container'
return scan, container_file_path
def mock_os_path_exists(self, arg):
return True
#patch('brain_db_helpers.volume_views_setup', mock_volume_views_setup)
#patch('os.path.exists', mock_os_path_exists)
def test_label_view(self):
rv = label_view(1)
assert(True) # I'll actually write tests when I figure out that I can!
print rv
Here is the error:
======================================================================
ERROR: brain_db.tests.test (unittest.loader.ModuleImportFailure)
----------------------------------------------------------------------
ImportError: Failed to import test module: brain_db.tests.test
Traceback (most recent call last):
File "/usr/local/lib/python2.7/unittest/loader.py", line 254, in _find_tests
module = self._get_module_from_name(name)
File "/usr/local/lib/python2.7/unittest/loader.py", line 232, in _get_module_from_name
__import__(name)
File "/usr/src/app/flask_brain_db/brain_db/tests/test.py", line 7, in <module>
from brain_db.views import label_view
File "/usr/src/app/flask_brain_db/brain_db/views.py", line 36, in <module>
#app.route('/surface_test')
File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1250, in decorator
self.add_url_rule(rule, endpoint, f, **options)
File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 66, in wrapper_func
return f(self, *args, **kwargs)
File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1221, in add_url_rule
'existing endpoint function: %s' % endpoint)
AssertionError: View function mapping is overwriting an existing endpoint function: surface_test
What I have done to try to solve my problem: I've read a bunch of the posts on SO that quote that same AssertionError. E.g. 1, 2. I can see that the general shape of the problem is that my routes have already been defined, and
from brain_db.views import label_view
is executing the views module again, thus redefining the routes, so I get an error thrown.
What I don't understand is how exactly I should avoid this. I need to be able to import a method into another file to be able to test it. Are all the routes supposed to be wrapped in if __name__ == main? I am brand new to Flask development and haven't yet seen example code where this is the case; I'm dubious that this is the correct solution; it's just the only thing that's offered when you try to search for preventing code from being executed on import.
The way I'm running my tests right now is via the file manage.py in the top level of my application. It contains the following method:
#manager.command
def test():
"""Runs the tests without coverage"""
tests = unittest.TestLoader().discover(start_dir='.', pattern='test*.py')
res = unittest.TextTestRunner(verbosity=2).run(tests)
sys.exit(not res.wasSuccessful())
I run python manage.py test at the command line.
It also might be relevant that while I've put the test that's failing in a submodule within brain_db, several tests run before it that hit routes defined in the app and test for the expected result. However, commenting out those tests has no effect on the way my test is failing.
Finally, I was initially getting an error at the line from flask_brain_db.brain_db.models import Scan:
ERROR: brain_db.tests.test (unittest.loader.ModuleImportFailure)
----------------------------------------------------------------------
ImportError: Failed to import test module: brain_db.tests.test
Traceback (most recent call last):
File "/usr/local/lib/python2.7/unittest/loader.py", line 254, in _find_tests
module = self._get_module_from_name(name)
File "/usr/local/lib/python2.7/unittest/loader.py", line 232, in _get_module_from_name
__import__(name)
File "/usr/src/app/flask_brain_db/brain_db/tests/test.py", line 5, in <module>
from flask_brain_db.brain_db.models import Scan
File "/usr/src/app/flask_brain_db/brain_db/models.py", line 6, in <module>
class Scan(db.Model):
File "/usr/local/lib/python2.7/site-packages/flask_sqlalchemy/model.py", line 67, in __init__
super(NameMetaMixin, cls).__init__(name, bases, d)
File "/usr/local/lib/python2.7/site-packages/flask_sqlalchemy/model.py", line 121, in __init__
super(BindMetaMixin, cls).__init__(name, bases, d)
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/ext/declarative/api.py", line 65, in __init__
_as_declarative(cls, classname, cls.__dict__)
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 116, in _as_declarative
_MapperConfig.setup_mapping(cls, classname, dict_)
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 144, in setup_mapping
cfg_cls(cls_, classname, dict_)
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 172, in __init__
self._setup_table()
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 465, in _setup_table
**table_kw)
File "/usr/local/lib/python2.7/site-packages/flask_sqlalchemy/model.py", line 90, in __table_cls__
return sa.Table(*args, **kwargs)
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/sql/schema.py", line 439, in __new__
"existing Table object." % key)
InvalidRequestError: Table 'scan' is already defined for this MetaData instance. Specify 'extend_existing=True' to redefine options and columns on an existing Table object.
I made it go away by including
__table_args__ = {'extend_existing': True}
In the model definition, but I don't know if I should have done that and I suspect I was just postponing the same problem I have now. It seems like the fundamental problem is that I don't know how to write tests without redefining a bunch of things that have been already been defined.
What is the correct way to approach this? Please let me know if I need to provide any other information.
You should be able to access your all view functions from your app object. Try removing the line "from brain_db.views import label_view", and instead define your label_view method after running set_up() using the below:
label_view = app.view_functions["label_view"]

Can't use class constructor argument in Python

I can't get what I'm doing wrong here. I'm defining a class with the following code:
import sqlite3 as lite
import sys
import os.path
class database:
def __init__(self,dbfname):
if os.path.isfile(dbfname):
self.con = lite.connect(dbfname)
else:
self.con = self.createDBfile(dbfname)
#Other methods...
Then, when I try to make an instance of the class
base = database("mydb.db")
I get an error saying that there is no "global" variable named dbfname .
Traceback (most recent call last):
File "testdb.py", line 67, in <module>
base = database("mydb.db")
File "testdb.py", line 13, in __init__
self.con = self.createDBfile(dbfname)
File "testdb.py", line 15, in createDBfile
if os.path.isfile(dbfname):
NameError: global name 'dbfname' is not defined
What would be the correct way to use the argument variable dbfname ?
This code looks fine. The error isn't in the code you posted though; it's in testdb.py on line 15 in the createDBfile() method (not in the __init__()).
How do I know this? Well, lets carefully look at the traceback Python gives us:
Traceback (most recent call last):
File "testdb.py", line 67, in <module>
base = database("mydb.db")
File "testdb.py", line 13, in __init__
self.con = self.createDBfile(dbfname)
File "testdb.py", line 15, in createDBfile
if os.path.isfile(dbfname):
NameError: global name 'dbfname' is not defined
Like the first line says, the most recent call is last. So you read a traceback from down to up (and not from up to down).
The very last line is the actual error, but just before that is:
File "testdb.py", line 15, in createDBfile
if os.path.isfile(dbfname):
So it says that in the file testdb.py, on line 15, in the method createDBfile() an error occurred. Python also prints out the contents of this line 15.
Above that is the call to the createDBfile() method in your __init__() function, and above that the call to the __init__() function (by creating the class instance).
You didn't post the contents of this createDBfile() method, so I can't tell you where exactly the error is. I suspect you did something wrong with the function arguments (perhaps as simple as a typo?)

UnboundLocalError initializing a python class

I am creating a Python class but it seems I can't get the constructor class to work properly. Here is my class:
class IQM_Prep(SBconcat):
def __init__(self,project_dir):
self.project_dir=project_dir #path to parent project dir
self.models_path=self.__get_models_path__() #path to parent models dir
self.experiments_path=self.__get_experiments_path__() #path to parent experiemnts dir
def __get_models_path__(self):
for i in os.listdir(self.project_dir):
if i=='models':
models_path=os.path.join(self.project_dir,i)
return models_path
def __get_experiments_path__(self):
for i in os.listdir(self.project_dir):
if i == 'experiments':
experiments_path= os.path.join(self.project_dir,i)
return experiments
When I initialize this class:
project_dir='D:\\MPhil\\Model_Building\\Models\\TGFB\\Vilar2006\\SBML_sh_ver\\vilar2006_SBSH_test7\\Python_project'
IQM= Modelling_Tools.IQM_Prep(project_dir)
I get the following error:
Traceback (most recent call last):
File "<ipython-input-49-7c46385755ce>", line 1, in <module>
runfile('D:/MPhil/Python/My_Python_Modules/Modelling_Tools/Modelling_Tools.py', wdir='D:/MPhil/Python/My_Python_Modules/Modelling_Tools')
File "C:\Anaconda1\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 585, in runfile
execfile(filename, namespace)
File "D:/MPhil/Python/My_Python_Modules/Modelling_Tools/Modelling_Tools.py", line 1655, in <module>
import test
File "test.py", line 19, in <module>
print parameter_file
File "Modelling_Tools.py", line 1536, in __init__
self.models_path=self.__get_models_path__() #path to parent models dir
File "Modelling_Tools.py", line 1543, in __get_models_path__
return models_path
UnboundLocalError: local variable 'models_path' referenced before assignment
Modelling_Tools is the name of my custom module.
Based on the traceback, it seems that either:
def __get_models_path__(self):
for i in os.listdir(self.project_dir): # 1. this never loops; or
if i=='models': # 2. this never evaluates True
models_path=os.path.join(self.project_dir,i) # hence this never happens
return models_path # and this causes an error
You should review the result of os.listdir(self.project_dir) to find out why; either the directory is empty or nothing in it is named models. You could initialise e.g. models_path = None at the start of the method, but that would just hide the problem until later.
Sidenote: per my comments, you should check out the style guide, particularly on naming conventions for methods...
models_path is initialized only when:
self.project_dir has some files/dirs and
one of this file/dir has name models
If one of this condition is not fullfiled, then models_path is not initialized.

Name conflicting in Theano

I am trying to import theano in a module, but I am getting a traceback:
File "/media/tarun/6A86CA8286CA4DEF/develop/pydy/pydy/codegen/code.py", line 16, in <module>
import theano
File "/usr/local/lib/python2.7/dist-packages/theano/__init__.py", line 44, in <module>
from theano.gof import \
File "/usr/local/lib/python2.7/dist-packages/theano/gof/__init__.py", line 38, in <module>
from theano.gof.cc import \
File "/usr/local/lib/python2.7/dist-packages/theano/gof/cc.py", line 55, in <module>
StrParam(""))
File "/usr/local/lib/python2.7/dist-packages/theano/configparser.py", line 223, in AddConfigVar
root=newroot, in_c_key=in_c_key)
File "/usr/local/lib/python2.7/dist-packages/theano/configparser.py", line 227, in AddConfigVar
configparam.fullname)
AttributeError: ('This name is already taken', 'gcc.cxxflags')
It seems that there is some name conflict in some config. Can anybody please point me to the same.
This error happens because some module, probably theano.gof, is imported twice. Usually, this is because a first call to import theano.gof gets started, registering 'gcc.cxxflags' in the configuration parser a first time, but then raises ImportError, which is catched and ignored.
Then, import theano.gof gets called again, tries to register the option again, which raises the exception you get.
Is there any traceback or error message before this one, or something that would give a hint of why the first import failed?
I got similar error using when using the jupyter notebook. Restarting kernel solved the issue.

Categories