Python cmd shell: handling undefined commands - python-3.x

I'm writing a shell that must be able to take an unlimited number of commands. I can't figure out from the docs (https://docs.python.org/3.6/library/cmd.html) which say:
Cmd.default(line) Method called on an input line when the command
prefix is not recognized. If this method is not overridden, it prints
an error message and returns.
I must be writing the default() method incorrectly?
I've tried this:
import cmd
class MyShell(cmd.Cmd):
def default():
print('you entered this unknown command: ')
if __name__ == '__main__':
MyShell().cmdloop()
but get this (when I enter 'hi' in the shell):
(Cmd) hi
Traceback (most recent call last):
File "/Users/david/anaconda/lib/python3.6/cmd.py", line 214, in onecmd
func = getattr(self, 'do_' + cmd)
AttributeError: 'MyShell' object has no attribute 'do_hi'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "bitmessage_shell.py", line 9, in <module>
MyShell().cmdloop()
File "/Users/david/anaconda/lib/python3.6/cmd.py", line 138, in cmdloop
stop = self.onecmd(line)
File "/Users/david/anaconda/lib/python3.6/cmd.py", line 216, in onecmd
return self.default(line)
TypeError: default() takes 0 positional arguments but 2 were given

def default():
print('you entered this unknown command: ')
that doesn't work in a class. You need at least the object argument (self), or make the method static/class using #staticmethod or #classmethod decorators (but not very convenient, you may need the object state at some point)
Moreover, the parent class seems to pass the line, so now you need 2 arguments:
def default(self,line):
print('you entered this unknown command: ',line)

Related

Application building using tkinter

I am trying to create an application that allow students to see the list of mandatory and elective courses using def key word in tkinter. This is the error i get after running the code.
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\mhm01\anaconda3\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "C:\Users\mhm01\AppData\Local\Temp\ipykernel_13464\560191512.py", line 25, in courses
label3.configure(courses)
File "C:\Users\mhm01\anaconda3\lib\tkinter\__init__.py", line 1646, in configure
return self._configure('configure', cnf, kw)
File "C:\Users\mhm01\anaconda3\lib\tkinter\__init__.py", line 1635, in _configure
return self._getconfigure1(_flatten((self._w, cmd, '-'+cnf)))
File "C:\Users\mhm01\anaconda3\lib\tkinter\__init__.py", line 1623, in _getconfigure1
x = self.tk.splitlist(self.tk.call(*args))
_tkinter.TclError: unknown option "-"
You have a key in the courses dictionary variable which is an invalid input to the .configure() method of the label class of tkinter - according to the error it looks like you have a key in courses called -. Try removing that (and ensure you only have valid keys in the dictionary you pass to configure)

unittest #patch return first tuple in list of the tuple

I have a problem with unittest. The patched method does not return a list of tuples, but only one tuple:
My code
from date import Date
from ditreport import DIT_report
from unittest import TestCase
from unittest.mock import patch, Mock
def mock_get_uuid_messages_with_tmpls():
result = [('43e89d3a-af91-465f-a2db-3147988d1168',), ('93963bf6-9f75-4ffe-80e6-745307ef0a10',),
('88e68d67-8969-4059-9f6c-ff161879eb38',), ('39191cbd-79bb-483a-8df7-04aaf72253f1',),
('44a685c4-fb12-4431-ae18-3fb220e4d3e7',), ('3eef8189-7509-4dc1-9d71-c04f1cfc0d88',),
('4736beae-aa55-4bb3-b41d-3f94b1b178d1',), ('260db4a6-aab8-4d34-b293-cbf5fe6c7400',),
('7b73dfe0-5b8a-4a63-8607-43827eeac4c0',), ('fb51668f-0d2f-4958-911d-07d57a73fe56',)]
return result
class TestDIT_report(TestCase):
def setUp(self):
self.date_start='2020-01-12'
self.date_end = '2020-02-01'
self.configfile='config/config.def.xml'
self.param='covid'
self.report = DIT_report(self.date_start, self.date_end, self.configfile)
#patch('ditreport.DIT_report.get_uuid_messages_with_tmpls', side_effect=mock_get_uuid_messages_with_tmpls())
def test_get_uuid_messages_with_tmpls(self, get_uuid_messages_with_tmpls):
messages_uuid = get_uuid_messages_with_tmpls()
self.assertEqual(10,len(messages_uuid))
messages_uuid should get a list of ten tuples but get the first tuple
Launching unittests with arguments python -m unittest
TestDIT_report.TestDIT_report.test_get_uuid_messages_with_tmpls in
/home/skif/PycharmProjects/reports
init config
Ran 1 test in 0.026s
FAILED (failures=1)
1 != 10
Expected :10 Actual :1
Traceback (most recent call last): File
"/home/skif/pycharm-2020/plugins/python/helpers/pycharm/teamcity/diff_tools.py",
line 32, in _patched_equals
old(self, first, second, msg) File "/usr/lib/python3.8/unittest/case.py", line 912, in assertEqual
assertion_func(first, second, msg=msg) File "/usr/lib/python3.8/unittest/case.py", line 905, in _baseAssertEqual
raise self.failureException(msg) AssertionError: 10 != 1
During handling of the above exception, another exception occurred:
Traceback (most recent call last): File
"/usr/lib/python3.8/unittest/case.py", line 60, in testPartExecutor
yield File "/usr/lib/python3.8/unittest/case.py", line 676, in run
self._callTestMethod(testMethod) File "/usr/lib/python3.8/unittest/case.py", line 633, in _callTestMethod
method() File "/usr/lib/python3.8/unittest/mock.py", line 1325, in patched
return func(*newargs, **newkeywargs) File "/home/skif/PycharmProjects/reports/TestDIT_report.py", line 86, in
test_get_uuid_messages_with_tmpls
self.assertEqual(10,len(messages_uuid))
Why do I get this error? Maybe I missed what parameter? But I have a similar code and it returns a normal list of tuples.
Its a simple mistake.
#patch('ditreport.DIT_report.get_uuid_messages_with_tmpls',
side_effect=mock_get_uuid_messages_with_tmpls())
should be
#patch('ditreport.DIT_report.get_uuid_messages_with_tmpls',
side_effect=mock_get_uuid_messages_with_tmpls)

Error : "Command raised an exception: TypeError: 'NoneType' object is not subscriptable" with function randrange()

I'm currently coding a discord bot, and I have a command that sends the URL of a random anime using a MyAnimeList api. Here is my code :
#client.command()
async def anime(ctx):
await ctx.send("Récupération d'un anime...")
anime = 0
while anime == 0:
async with ctx.typing():
try:
ref = randrange(1, 40500)
anime = Anime(ref)
await ctx.send(anime)
except ValueError as err:
if str(err) == 'No such id on MyAnimeList':
pass
else:
pass
I'm using a while loop to retry if the api returns a 404 error (because not every single anime id is used on myanimelist.net)
The error i'm getting is :
Ignoring exception in command anime:
Traceback (most recent call last):
File "/home/container/.local/lib/python3.6/site-packages/discord/ext/commands/core.py", line 83, in wrapped
ret = await coro(*args, **kwargs)
File "bot.py", line 46, in anime
anime = Anime(ref)
File "/home/container/.local/lib/python3.6/site-packages/mal/anime.py", line 8, in __init__
super().__init__(mal_id, "anime", timeout)
File "/home/container/.local/lib/python3.6/site-packages/mal/mal.py", line 15, in __init__
title = self._page.find("meta", property="og:title")["content"]
TypeError: 'NoneType' object is not subscriptable
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/container/.local/lib/python3.6/site-packages/discord/ext/commands/bot.py", line 892, in invoke
await ctx.command.invoke(ctx)
File "/home/container/.local/lib/python3.6/site-packages/discord/ext/commands/core.py", line 797, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "/home/container/.local/lib/python3.6/site-packages/discord/ext/commands/core.py", line 92, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: 'NoneType' object is not subscriptable
I think that the problem comes from the fonction randrange(). When i was looking for a solution, every single person with the same issue had a code that was involving lists, but I don't have any in my code...
I'm using Python 3.7.6.
The problem probably comes from the mal-api library itself...
You might be running into rate limiting or something else that is interfering with the web pages you're getting back. You could try writing a wrapper class around Anime to look at the _page attribute to see what the problem is:
class MyAnime(Anime):
def __init__(self, ref):
try:
super().__init__(ref)
except:
print(self._page)
print(self._page.find("meta"))
print(self._page.find("meta", property="og:title"))

How can I catch an error without using try/except?

Is there something that I could use to catch errors in python without using a try/except?
I'm thinking of something like this:
main.py
from catch_errors import catch_NameError
print(this_variable_is_not_defined)
catch_errors.py
def catch_NameError(error):
if type(error) == NameError:
print("You didn't define the error")
The output would be:
You didn't define the error
Instead of:
Traceback (most recent call last):
File "main.py", line 1, in <module>
print(this_variable_is_not_defined)
NameError: name 'this_variable_is_not_defined' is not defined
It can be done by creating a context manager, but it gives questionable benefit over an explicit try:except:. You will have to use the with statement, so it will be clear where behavior will change. In this example, I am using contextlib.contextmanager to do this, which saves the tedium of creating a class with __enter__ and __exit__ methods.
from contextlib import contextmanager
#contextmanager
def IgnoreNameErrorExceptions():
"""Context manager to ignore NameErrors."""
try:
yield
except NameError as e:
print(e) # You can print whatever you want here.
with IgnoreNameErrorExceptions():
print(this_variable_is_not_defined)
This will output
name 'this_variable_is_not_defined' is not defined

TypeError: object.__new__() takes no parameters when using generators

I am a newbie in python.I need to print all the numbers from 1 to 100.When i run this code,i got this error
Traceback (most recent call last):
File "C:\Eclipse\workspace\firstpython\src\oopsegmant.py", line 14, in <module>
p = Prime(1)
TypeError: object.__new__() takes no parameters
The program is like this
class Prime():
def _init_(self,i):
self.i=i
def print_value(self):
while(True):
yield(self.i)
self.i+=self.i
p = Prime(1)
for numb in p.print_value():
if(numb>100):
break
print(numb)
_init_ should be spelled with double underscores, __init__.
All special methods names are enclosed in double underscores.
Also the print_value method should be indented under the class to be a part of it.

Resources