Why can't I pickle my custom exception in Python - python-3.x

I am using Python 3.6. I defined a custom exception following this page: https://docs.python.org/3.6/tutorial/errors.html
class MyException(Exception):
def __init__(self, a):
self.a = a
Now, if I try to pickle + unpickle this exception, I get the following error:
>> e = MyException(a=1); pickle.loads(pickle.dumps(e))
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-44-413e2ac6234d> in <module>
----> 1 e = MyException(a=1); pickle.loads(pickle.dumps(e))
TypeError: __init__() missing 1 required positional argument: 'a'
Does anyone know why?

Seems to be that the Exception baseclass has special treatment for named arguments (likely in its implementation of __new__)
you can fix this by properly calling the base class in your __init__ method:
>>> class MyException(Exception):
... def __init__(self, a):
... super().__init__(a)
... self.a = a
...
>>> pickle.loads(pickle.dumps(MyException(a=1)))
MyException(1,)

Related

Class assignment: object not callable [duplicate]

As a starting developer in Python I've seen this error message many times appearing in my console but I don't fully understand what does it means.
Could anyone tell me, in a general way, what kind of action produces this error?
That error occurs when you try to call, with (), an object that is not callable.
A callable object can be a function or a class (that implements __call__ method). According to Python Docs:
object.__call__(self[, args...]): Called when the instance is “called” as a function
For example:
x = 1
print x()
x is not a callable object, but you are trying to call it as if it were it. This example produces the error:
TypeError: 'int' object is not callable
For better understaing of what is a callable object read this answer in another SO post.
The other answers detail the reason for the error. A possible cause (to check) may be your class has a variable and method with the same name, which you then call. Python accesses the variable as a callable - with ().
e.g. Class A defines self.a and self.a():
>>> class A:
... def __init__(self, val):
... self.a = val
... def a(self):
... return self.a
...
>>> my_a = A(12)
>>> val = my_a.a()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
>>>
The action occurs when you attempt to call an object which is not a function, as with (). For instance, this will produce the error:
>>> a = 5
>>> a()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
Class instances can also be called if they define a method __call__
One common mistake that causes this error is trying to look up a list or dictionary element, but using parentheses instead of square brackets, i.e. (0) instead of [0]
The exception is raised when you try to call not callable object. Callable objects are (functions, methods, objects with __call__)
>>> f = 1
>>> callable(f)
False
>>> f()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
I came across this error message through a silly mistake. A classic example of Python giving you plenty of room to make a fool of yourself. Observe:
class DOH(object):
def __init__(self, property=None):
self.property=property
def property():
return property
x = DOH(1)
print(x.property())
Results
$ python3 t.py
Traceback (most recent call last):
File "t.py", line 9, in <module>
print(x.property())
TypeError: 'int' object is not callable
The problem here of course is that the function is overwritten with a property.

Explicit kwarg in __prepare__ raises TypeError __init_subclass__

Hi I am attempting to learn the class creation process better. I am interested in the aspect of class parameterization. Why do I get an error if I make an keyword argument in __prepare__? If I just use the default value, the class is defined properly but if I explicitly pass the explicit keyword argument, I get a TypeError in __init_subclass__?
I am using python 3.10
In [13]: class Meta(type):
...: #classmethod
...: def __prepare__(mcs, *args, required_kwarg="foo", **kwargs):
...: print(required_kwarg)
...: return {}
In [14]: class Foo(metaclass=Meta):
...: ...
foo
In [15]: class Foo2(metaclass=Meta, required_kwarg="foo2"):
...: ...
foo2
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Input In [15], in <module>
----> 1 class Foo2(metaclass=Meta, required_kwarg="foo2"):
2 ...
TypeError: Foo2.__init_subclass__() takes no keyword arguments
It seems like passing any kind of keyword argument through the class definition throws an error with __init_subclass__. For example, I accept **kwargs in __prepare__ but do not specify an explicit keyword argument. I still get the same TypeError in __init_subclass__.
In [1]: class Meta(type):
...: #classmethod
...: def __prepare__(mcs, *args, **kwargs):
...: if "required_kwarg" not in kwargs:
...: raise TypeError('missing "required_kwarg" keyword argument')
...: else:
...: required_kwarg = kwargs["required_kwarg"]
...: print(required_kwarg)
...: return {}
In [2]: class Foo2(metaclass=Meta, required_kwarg="foo2"):
...: ...
foo2
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Input In [2], in <module>
----> 1 class Foo2(metaclass=Meta, required_kwarg="foo2"):
2 ...
TypeError: Foo2.__init_subclass__() takes no keyword arguments
Is there no way around this? Am I using __prepare__ incorrectly? Should __init_subclass__ not just accept all **kwargs by default to deal with this?

Class is not running method (simple) How do i run this?

I am having a hard time with this exercise, I am not sure why this doesn't work
Output
Traceback (most recent call last):
File "main.py", line 16, in <module>
conf_module.run()
TypeError: run() missing 1 required positional argument: 'self'
My code
class Confidence:
def __init__(self):
self.string = 'X-DSPAM-Confidence: 0.8475'
def colon(self):
self.col_pos = self.string.find(':')
self.number = self.string[self.col_pos + 1]
self.confidence = float(self.number)
print(self.confidence)
def run(self):
self.colon()
conf_module = Confidence
conf_module.run()
Im sure its something simple, I just dont understand it right now. thank you for the help.

Pylint super constructor doesn't trigger E1120

Pylint has an existing error E1120 which will trigger when a value is missing from a constructor. This, however, doesn't trigger in inheritance. For example, look at this:
class Parent(object):
def __init__(self, x):
self.x = x
class Child(Parent):
def __init__(self):
super().__init__()
if __name__ == "__main__":
c = Child()
p = Parent()
As you can see, the Parent class constructor takes an argument x but the Child, which inherits from it, is not passing in anything.
If we run pylint --errors-only X.py just for the errors we get this one:
X.py 13:8: E1120: No value for argument 'x' in constructor call (no-value-for-parameter)
This is for the direct call to Parent() at the end of the file. There is no error generated from the instantiation of Child() nor from call to super().__init__() which is an error. Specifically, running this directly with python results in:
Traceback (most recent call last):
File "X.py", line 12, in <module>
c = Child()
File "X.py", line 8, in __init__
super().__init__()
TypeError: __init__() missing 1 required positional argument: 'x'
Therefore I would expect pylint to catch this as an error. Am I missing something? Or is this an issue in pylint?
Relevant versions:
pylint 2.1.1
astroid 2.0.4
Python 3.5.2 (default, Nov 23 2017, 16:37:01)

python3 object has no attriubute

I have a file called entities.py, which contains the following code:
class EntityClass:
entities = {}
def __init__(self, parent=None):
.......
def show_all(self):
......
But then, when I run python 3 and type the command as follows:
>>> import entities
>>> ent = entities.EntityClass()
>>> ent.show_all()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'EntityClass' object has no attribute 'show_all'
show_all should clearly be an attribute for EntityClass.
This of course worked perfectly in Python 2, and I'm assuming it's a Python 3 issue...
Is there a work around for this?
From the code posted, it looks like your indentation levels are wrong, you have declared the show_all() method on the module, not the class.
def_show_all(self): Should be indented to the same level as entities = {}
class EntityClass:
entities ={}
def __init__(self,parent=None):
.......
def show_all(self):
......

Resources