KeyError if I change constructor variable names - python

I'm going crazy trying to perform simple editing while creating a Python class constructor. I can create the simple class and constructor variable but once I try to change the names of the variable I get a KeyError.
The class is below:
class Collect:
def __init__(self, **kwargs):
self.foo = kwargs["foo"]
And the script where I instantiate the class and print out its attributes is below:
import mapper as m
payload = m.Collect(foo="Hello")
print(payload.foo)
Now this works just fine, but if I change "foo" to "bar" I get a KeyError Like below:
class Collect:
def __init__(self, **kwargs):
self.bar = kwargs["bar"]
and then running:
import mapper as m
payload = m.Collect(bar="Hello")
print(payload.bar)
will throw the following error:
Traceback (most recent call last): File "<stdin>", line 1, in
<module> File
"/path/to/mapper.py",
line 8, in __init__
self.bar = kwargs["bar"] KeyError: 'foo'
And the print function will throw the error below:
Traceback (most recent call last): File "<stdin>", line 1, in
<module> AttributeError: 'Collect' object has no attribute 'bar'
The weird thing is that if I hit save and then close VSCode and reopen, the new class with bar will work just fine. And, also even if I don't close VSCode the class will instantiate and the print statement will run just fine when I switch to Debug mode and run it. But when I try to highlight it and run a selection it throws that error.
How can I just test if the code works using the run selection operations and not relying on running in debug mode with breakpoints or having to close and reopen VSCode?

The solution was to reload my Python session. The VSCode reload extension makes this easy.

Related

AttributeError with extended class in Python

I'm trying to create a new method for a class from a different file (not the file where the class was defined). My code is:
from derivations import derivation
class Derivation(derivation.Derivation):
def autoderive(self, index):
...
deriv = derivation.Derivation()
But if I try to run this method from the terminal, it doesn't work:
>>> deriv.autoderive()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Derivation' object has no attribute 'autoderive'
I don't have problems with the "native" methods. And I'm working with a fork of this: https://github.com/alexwarstadt/minimalism
Thank you very much.
I do not know much about the derivation module, but you are not creating an instance of your Derivation class, where you have defined the autoderive method, by doing this:
deriv = derivation.Derivation()
To create an instance of your custom class Derivation, that derives from derivation.Derivation():
deriv = Derivation()

Hide Traceback message for class exceptions in Python

Can anyone advice what would be effective way to hide the Trackback from a python class exception. We know sys.tracebacklimit = 0 can be useful for hiding the trace, but not sure how this can be implemented in a class.
For example, we have a test.py file with example code:
class FooError(Exception):
pass
class Foo():
def __init__(self, *args):
if len(args) != 2:
raise FooError('Input must be two parameters')
x, y = args
self.x = x
self.y = y
When we run the cmd to run this file, we get
>>> from test import *
>>> Foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/test.py", line 8, in __init__
raise FooError('Input must be two parameters')
test.FooError: Input must be two parameters
However, we only expect the error message should be displayed:
test.FooError: Input must be two parameters
Any code changes should be included in the class to reach this?
But why? Are you trying to make debugging your program harder?
Either way, this is really about how exceptions and tracebacks are printed by the default implementation. If you really want the console exception print implementation not to print a traceback for your errors, you can set sys.excepthook to a custom implementation that doesn't print the traceback.
This won't prevent any other try/except block from being able to access the traceback though, of course.

Class instance fails isinstance check

Hi
I have some code on my CI failing (local runs do not fail).
The problem is that class instance fails isinstance() check.
Code:
File: main.py
class MyController(SuperController):
# Overrides default definition of get_variables_context()
from my_options import get_variables_context
File: my_options.py
...
def get_variables_context(self: SuperController, **kwargs):
from main import MyController
self: MyController
print(f"type(self) is {type(self)} (it {'IS' if (isinstance(self, MyController)) else 'IS NOT'} a subclass of MyController)")
_super = super(MyController, self).get_variables_context(**kwargs) or dict()
_super.update(result)
return _super
Got output and error:
type(self) is <class '__main__.SomeController'> (it IS NOT a subclass of SomeController
Traceback (most recent call last):
File "main.py", line 24, in <module>
SomeController.main(**params)
File "/builds/RND/my/rcv-nginx/tests/nginx_tests/flow.py", line 391, in main
_tests_suite, _, _ = self.prepare()
File "/builds/RND/my/rcv-nginx/tests/nginx_tests/flow.py", line 359, in prepare
context['variables_context'] = self.get_variables_context(**context)
File "/builds/RND/my/tests/integration/my_options.py", line 81, in get_variables_context
_super = super(SomeController, self).get_variables_context(**kwargs) or dict()
TypeError: super(type, obj): obj must be an instance or subtype of type
I've found the solution while investigating the root cause.
In the local run, ...
I actually call the python unittest which then calls main.py which then creates a class MyController which then calls my_options.py, and the class is added to the loaded module 'main'.
Then, MyController.get_variables_context asks for the module 'main', which is already loaded, then for the class MyController in that module, so the same type instance is returned and type check succeeds.
In the CI run, ...
I call directly main.py with the argument "test" (which should create a controller and run all tests from it via unittest), so the class MyController is created inside module __main__. MyController.get_variables_context still asks for the MyController class in main.py, but the module 'main' is not loaded here, so python loads it, creates new class MyController, and then returns it.
So, basically the answer is ...
to move MyController from main.py to the other file, i.e. controller.py

Why do I get an AttributeError on getattr in my execute method?

The code below is used as part of a SimpleXMLRPCServer to receive commands from a Java client I've written. The Java client will just call this execute function and pass in a function name from the CameraAssembler class.
from nsCamera.CameraAssembler import CameraAssembler
class MyFunctions:
ca = None
def initialize(self):
# Create Camera object
self.ca = CameraAssembler(commname=COMM, boardname=BOARD, sensorname=SENSOR, verbose=True)
return True
def execute(self, code):
func = getattr(self.ca,code)
output = func()
return output
myfuncs = MyFunctions()
myfuncs.initialize()
output = myfuncs.execute('arm()')
print(output)
Output:
Traceback (most recent call last):
File "pyTestServer.py", line 31, in <module>
output = myfuncs.execute("arm()")
File "pyTestServer.py", line 21, in execute
func = getattr(MyFunctions.ca,code)
AttributeError: CameraAssembler instance has no attribute 'arm()'
Your parentheses are in the wrong place. The attribute is not called arm(), it's called arm; you need to call the result of getting that attribute.
output = myfuncs.execute('arm')()
(Note, this code isn't particularly idiomatic. In particular, I can't see why you're setting ca as a class attribute, rather than an instance one. Also, initialisation usually goes in an __init__ method, which is called automatically on instantiation.)

name 'self' is not defined when doing an unittest?

Edit
So I did try again, with a new file called test2.py and it works. I packaged repoman , and test.py is in the src folder. I modified test.py after I created and installed my repoman egg. I think that's the problem. But thanks for the help. Do you guys think that's the exact reason?
import unittest
import requests
from repoman.core import ultraman, supported
from repoman.ext import writefile,locate_repo
class TestWriteFile(unittest.TestCase):
def setUp(self):
self.username = 'dummy'
self.password = 'dummy'
self.remote = 'http://192.168.1.138:6666/scm/hg/NCL'
def test_scm_permission(self):
"""
Test SCM login.
"""
r = requests.get("http://192.168.1.138:6666/scm/", auth=(self.username, self.password))
self.assertTrue(r.ok)
if __name__ == '__main__':
unittest.main()
Running python test.py I get this error:
Traceback (most recent call last):
File "test.py", line 7, in <module>
class TestWriteFile(unittest.TestCase):
File "test.py", line 19, in TestWriteFile
self.assertTrue(r.ok)
NameError: name 'self' is not defined
I don't think I need to overwrite __init__ function, do I? What's causing this? Why is self not defined? I already declared my superclass unittest.TestCase
Thanks.
I basically learned it from the official sample: Unittest - Basic Example
I'm not sure where the problem is coming from -- whether it's a copying error or the wrong test.py is being executed [update: or some mixed tabs-and-spaces issue, I can never figure out when those get flagged and when they don't] -- but the root cause is almost certainly an indentation error.
Note that the error message is
NameError: name 'self' is not defined
and not
NameError: global name 'self' is not defined
which #Rik Poggi got. This is exactly what happens if you move the self.assertTrue one level in/up:
~/coding$ cat test_good_indentation.py
import unittest
class TestWriteFile(unittest.TestCase):
def test(self):
"""
Doc goes here.
"""
self.assertTrue(1)
if __name__ == '__main__':
unittest.main()
~/coding$ python test_good_indentation.py
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
versus
~/coding$ cat test_bad_indentation.py
import unittest
class TestWriteFile(unittest.TestCase):
def test(self):
"""
Doc goes here.
"""
self.assertTrue(1)
if __name__ == '__main__':
unittest.main()
~/coding$ python test_bad_indentation.py
Traceback (most recent call last):
File "test_bad_indentation.py", line 3, in <module>
class TestWriteFile(unittest.TestCase):
File "test_bad_indentation.py", line 8, in TestWriteFile
self.assertTrue(1)
NameError: name 'self' is not defined
I don't think that what you showed is the actual code that get executed.
I and others belive that, for a couple of reasons:
If self.assertTrue(r.ok) fails then the line before will too. Therefore self.assertTrue(r.ok) won't execute. (as David Heffernan said)
And because your code looks fine.
I'd say that you probably made a typo of this kind:
def test_scm_permission(self):
^
|
and wrote something here that's not self
In some file that get executed instead of the one you're showing.
Take a look at this example:
# test.py
class MyClass:
def func(sel): # typo error here
self.name = 10
obj = MyClass()
obj.func()
And when I tried to run:
$ python3 test.py
Traceback (most recent call last):
File "test.py", line 8, in <module>
obj.func()
File "test.py", line 4, in func
self.name = 10
NameError: global name 'self' is not defined
Having a traceback similar to yours.
Note: Also if I'm not counting wrong self.assertTrue(r.ok) is on line 18, instead of line 19 (which is the number showed in your traceback).
This is a rewording of David Heffernan's comment.
The code you posted cannot be the cause of that traceback.
Consider these two lines from your code:
r = requests.get("http://192.168.1.138:6666/scm/", auth=(self.username, self.password))
self.assertTrue(r.ok)
The traceback says the error (NameError: name 'self' is not defined)
occurs on the second line (self.assertTrue(r.ok)). However, this cannot have been the case because the first line refers to self. If self were not defined, we would not get past the first line.
Therefore, the code you posted is not the code you ran.
This is an old question, but thought I'd add my two cents as it was not mentioned here. I agree with others that there is some type of spelling error in the original code. Look at this code carefully:
import unittest
import requests
class TestWriteFile(unittest.TestCase):
def setup(self):
self.username = 'dummy'
def test_scm_permission(self):
r = requests.get("http://192.168.1.138:6666/scm/", auth=(self.username, self.password))
self.assertTrue(r.ok)
The code appears okay at first glance (and lint tools will not complain); however, I wrote setup, instead of setUp (note the capital U). This causes self.username not to be defined in the test_scm_permission context, because python did not automatically call my mispelled function name. This is something else to check if you're running into this type of error, but are certain you've defined the class members correctly.
I had the same problem, but not with self. It was a regular variable, defined the line before the error occured.
It was apparently due to ... mixin tabs and spaces.
I replaced all tabs by 4 spaces, and the problem disappeared.
For some unspecified reason, instead of the traditional indentation error, I had this one.

Categories

Resources