I've been following this amazing (video) tutorial to create custom user defined GDB command using python
here is my code
import os
import gdb
class BugReport (gdb.Command):
"""Collect required info for a bug report"""
def __init__(self):
super(BugReport, self).__init__("bugreport", gdb.COMMAND_USER)
def invoke(self, arg, from_tty):
pagination = gdb.parameter("pagination")
if pagination: gdb.execute("set pagination off")
f = open("/tmp/bugreport.txt", "w")
f.write(gdb.execute("thread apply all backtrace full", to_string=True))
f.close()
os.system("uname -a >> /tmp/bugreport.txt")
if pagination: gdb.execute("set pagination on")
BugReport()
but when I try to source this code inside gdb I get following error:
(gdb) source mybugreport.py
Traceback (most recent call last):
File "mybugreport.py", line 19, in <module>
BugReport()
TypeError: function missing required argument 'name' (pos 1)
what I'm doing wrong?
what I'm doing wrong?
Python is indentation-sensitive. You want:
class BugReport (gdb.Command):
"""Collect required info for a bug report"""
def __init__(self):
super(BugReport, self).__init__("bugreport", gdb.COMMAND_USER)
def invoke(self, arg, from_tty):
pagination = gdb.parameter("pagination")
...
BugReport()
Related
I'm using cloup for my CLI for its constraints feature.
I have some commands a and b which have no common arguments.
import cloup
#cloup.group()
def cli():
pass
#cli.command(show_constraints=True)
#cloup.option("--foo")
def a(**kwargs):
print("hello")
#cli.command(show_constraints=True)
#cloup.option("--bar")
def b():
pass
cli()
I want a to be the default command. So, I'd like the following output:
$ python3 main.py
Usage: main.py [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
a
b
$ python3 main.py a --foo hey
hello
So far, this works as expected. Now I also want a to be the default command, thus I'd like to see:
$ python3 main.py --foo hey
hello
I know that I can have behaviour in cli as follows:
#cloup.group(invoke_without_command=True)
def cli():
print("custom behaviour")
That will give
$ python3 main.py
custom behaviour
I thought that I could forward the call to a in the cli function, but the group cli does not know the option --foo of command a:
$ python3 main.py --foo hey
Usage: main.py [OPTIONS] COMMAND [ARGS]...
Try 'main.py --help' for help.
Error: No such option: --foo
I'm stuck here. I found an answer to the question here (A command without name, in Click), but I have to use cloup.group. So if I applied the solution there ...
#cloup.group(cls=DefaultGroup, default='a',default_if_no_args=True)
def cli():
pass
... I'd get
Traceback (most recent call last):
File "main.py", line 11, in <module>
#cloup.option("--foo")
File "<SNIP>/.venv_3.6.9/lib/python3.6/site-packages/click/core.py", line 1834, in decorator
cmd = command(*args, **kwargs)(f)
File "<SNIP>/.venv_3.6.9/lib/python3.6/site-packages/click/decorators.py", line 184, in decorator
cmd = _make_command(f, name, attrs, cls) # type: ignore
File "<SNIP>/.venv_3.6.9/lib/python3.6/site-packages/click/decorators.py", line 152, in _make_command
**attrs,
TypeError: __init__() got an unexpected keyword argument 'show_constraints'
And that's only the tip of the spear - any other features from cloup.group also become unavailable.
I guess one could merge the groups of cloup and click-default-group, but that looks horribly time-consuming. Is there an easier way to get a default command in cloup?
I also found https://click.palletsprojects.com/en/8.0.x/api/?highlight=group#click.Context.ignore_unknown_options. But if I understood correctly, only commands have a context and groups do not, so it wouldn't help.
Author of Cloup here. You can try this:
"""
This example requires click-default-group.
"""
import cloup
from click import Context, HelpFormatter
from click_default_group import DefaultGroup
class GroupWithDefaultCommand(cloup.Group, DefaultGroup):
# Optional: mark default command with "*"
def format_subcommand_name(
self, ctx: click.Context, name: str, cmd: click.Command
) -> str:
if name == self.default_cmd_name:
name = name + "*"
return super().format_subcommand_name(ctx, name, cmd)
#cloup.group(cls=GroupWithDefaultCommand, default='alice')
def cli():
pass
#cli.command()
#cloup.option("--foo")
def alice(**kwargs):
print("Called alice with", kwargs)
#cli.command()
#cloup.option("--bar")
def bob(**kwargs):
print("Called bob with", kwargs)
if __name__ == '__main__':
cli()
AFAICS now, you'll only lose the "Did you mean" suggestion for mistyped commands (from Cloup) and the "*" indicating the dafault command (from click-default-group) (it was actually pretty easy to implement that with the method Group.format_subcommand_name introduced by Cloup). Let me know if you find any other problems. If it works well, I'll maybe add it to the examples folder.
Nonetheless, I'd suggest you to not use a default command at all. In click-default-group issue tracker, you can see it conflicts with click-help-colors and click-repl. So, unless you're not afraid of fixing issue that may potentially arise from having a default command, don't have one. As an alternative, you can just suggest your users to define an alias for the default command (e.g. by using the alias unix command).
I'm trying to declare a new tool to the CherryPy toolbox following the examples from the docs: Docs CherryPy Tools.
According to the examples I have written:
import cherrypy
def myTool():
print ("myTool")
class Root(object):
#cherrypy.expose
#cherrypy.tools.mytool()
def index(self):
return "Hello World!"
if __name__ == '__main__':
cherrypy.tools.mytool = cherrypy.Tool('before_finalize', myTool)
cherrypy.quickstart(Root(), '/')
This results in the following error:
Traceback (most recent call last):
File "server.py", line 6, in <module>
class Root(object):
File "server.py", line 8, in Root
#cherrypy.tools.mytool()
AttributeError: 'Toolbox' object has no attribute 'mytool'
However if I change the notation to the following it works as expected.
import cherrypy
def myTool():
print ("myTool")
class Root(object):
#cherrypy.expose
def index(self):
return "Hello World!"
index._cp_config = {'tools.mytool.on': True}
if __name__ == '__main__':
cherrypy.tools.mytool = cherrypy.Tool('before_finalize', myTool)
cherrypy.quickstart(Root(), '/')
The docs says that both methods have the same effect, but not in my case. If anyone knows what I'm doing wrong I'll be very grateful.
The tool should not be defined globally, hence the #cherrypy.tools.mytool() notation.
I'm using python 3.6.
The problem is the misunderstanding of the evaluation order of python (top-down), at the time the class is defined the tool has not been defined.
You can define the tool in another file import at the top (before the class definition) and it should work.
The second form works, because the configuration is done indirectly using strings in the config, not the real tool objects.
I am learning monogoDB, I am beginner but I am facing some errors. What is my coding error and tell me the solution for that?
this is post.py file
import uuid
from database import Database
import datetime
class Post (object):
def __init__(self,blog_id,title,content,author,date=datetime.datetime.utcnow(),id=None):
self.blog_id=blog_id
self.title=title
self.content=content
self.author=author
self.created_date=date
self.id=uuid.uuid4().hex if id is None else id
def save_to_mongo(self):
Database.insert(collection='students',data=self.json())
def json(self):
return {
'id':self.id,
'blog_id':self.blog_id,
'author':self.author,
'content':self.content,
'title':self.title,
'created_date':self.created_date
}
#staticmethod
def from_mongo(id):
return Database.find_one(collection='students',query={'id':id})
#staticmethod
def from_blog(id):
return [post for post in Database.find(collection='students',query={'blog_id':id})]
database.py file
import pymongo
class Database(object):
URI="mongodb//127.0.0.1:27017"
DATABASE=None
#staticmethod
def initialize():
client=pymongo.MongoClient(Database.URI)
Database.DATABASE=client['local']
#staticmethod
def insert(collection,data):
Database.DATABASE[collection].insert(data)
#staticmethod
def insert(collection,query):
return Database.DATABASE[collection].find(data)
#staticmethod
def insert(collection,query):
return Database.DATABASE[collection].find_one(data)
this is test.py file
from database import Database
from post import Post
Database.initialize()
post=Post(blog_id="123",title="Anoother great post",content="This is some
sample content",author="rahul")
post.save_to_mongo()
i got the following error during running test.py
[Running] python "d:\myprograms\python\test.py"
Traceback (most recent call last):
File "d:\myprograms\python\test.py", line 9, in <module>
post.save_to_mongo()
File "d:\myprograms\python\post.py", line 15, in save_to_mongo
Database.insert(collection='students',data=self.json())
TypeError: insert() got an unexpected keyword argument 'data'
I am getting following error when i try to run my first python script for gdb
TypeError: Required argument 'name' (pos 1) not found
my script
import gdb
class HelloWorld (gdb.Command):
"""Greet the whole world."""
def __init__ (self):
super (HelloWorld, self).__init__ ("hello-world", gdb.COMMAND_USER)
def invoke (self, arg, from_tty):
print "Hello, World!"
HelloWorld ()
i am just trying to learn python scripting for gdb
error
(gdb) source firstScript.py
Traceback (most recent call last):
File "gdbtest2.py", line 12, in <module>
HelloWorld ()
TypeError: Required argument 'name' (pos 1) not found
I have a simillar problem
import gdb
class Open(gdb.Command):
"""test open"""
def __inti__(self):
super().__inti__('_open', gdb.COMMAND_USER)
def invoke(self, args, from_tty):
argv = gdb.string_to_argv(args)
print(argv)
Open()
bug is the typing error of "__init__"", I know this is stupid, but I just did it. maybe it will help someone else.
I have my own exceptions and i want to test farther fields in the ex other then the message.
Reading this thread i tried the idea of using a context. I wrote this generic function
def test_runtime_error(test, exception_type, message, display_parameter, path, callable_obj, *args):
pdb.set_trace()
with test.assertRaises(exception_type) as cx:
callable_obj(*args)
ex = cx.exception
test.assertEqual(ex.message,message)
test.assertEqual(ex.display_parameter,display_parameter)
test.assertEqual(ex.path,path)
The path and display_parameter are my own specific fields. I'm not inventing the wheel here, i took most of it from the source.
I'm using it like that
class ExceptionsTest(unittest.TestCase):
def test_something(self):
data = {"name" : "A"}
obj = MyModel.objects.get(pk=1)
test_runtime_error(self,CustomException, 'message', 'A', [], obj.create, data)
The arguments are passed correctly into the callable_obj. the function raises the expected exception. but right after the execution of callable_obj the function breaks and the exception is not fetched. BTW, when i ran the same code in the test it self it worked fine.
Whats wrong here ?
The issue here appears to be this line:
pdb.set_trace()
If you leave it in, but don't have import pdb, the code below will fail with:
E
======================================================================
ERROR: testRaises (__main__.ExceptionTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "./except.py", line 22, in testRaises
self.verifyComplexException(MyException, 'asdf', RaiseException, 'asdf')
File "./except.py", line 14, in verifyComplexException
pdb.set_trace()
NameError: global name 'pdb' is not defined
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (errors=1)
which matches your description. If you do add the import pdb line, it will drop into the debugger, which is a completely different behavior that cannot be confused for the exit with E or exit with F status, so it can't be that.
Here's a complete example based on this idea which works as intended (licensed under Apache 2.0; see my repo):
import unittest
class MyException(Exception):
def __init__(self, message):
self.message = message
def RaiseException(message):
raise MyException(message)
class ExceptionTest(unittest.TestCase):
def verifyComplexException(self, exception_class, message, callable, *args):
with self.assertRaises(exception_class) as cm:
callable(*args)
exception = cm.exception
self.assertEqual(exception.message, message)
def testRaises(self):
self.verifyComplexException(MyException, 'asdf', RaiseException, 'asdf')
if __name__ == '__main__':
unittest.main()