0

I am having difficulty fully defining the class in my Python code. I have played around with it, but have had no luck.

from telegram import InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import Updater, CommandHandler, CallbackQueryHandler, \
    ConversationHandler, MessageHandler, BaseFilter, run_async, Filters
     

class TelegramBot:
    class PrivateUserFilter(BaseFilter):
        def __init__(self, user_id):
            self.user_id = int(user_id)

        def filter(self, message):
            return message.from_user.id == self.user_id

    def __init__(self, token: str, allowed_user_id): 
        self.updater = Updater(token=token)
        self.dispatcher = self.updater.dispatcher
        self.private_filter = PrivateUserFilter(allowed_user_id)
        self._prepare()

It's throwing the following exception:

~\OneDrive - yyy\..\core\telegrambot.py in __init__(self, token, allowed_user_id)
---> 44         self.private_filter = PrivateUserFilter(allowed_user_id)
     45         self._prepare()
     46 

NameError: name 'PrivateUserFilter' is not defined
Tom
  • 1
  • 1
  • `TelegramBot.PrivateUserFilter`? But do you really need to define the class `PrivateUserFilter` in the class `TelegramBot`? – Matthias Mar 17 '21 at 12:55
  • 1
    Does this answer your question? [Is there a benefit to defining a class inside another class in Python?](https://stackoverflow.com/questions/78799/is-there-a-benefit-to-defining-a-class-inside-another-class-in-python) – rfkortekaas Mar 17 '21 at 12:55

2 Answers2

0

You're putting a class inside an other class. This means the "inside" class is only available as an attribute on the first.

And while some some systems make use of such nested classes e.g. Django somewhat famously uses nested classes for some types of meta-information of models and forms, here it seems completely useless.

Just move PrivateUserFilter to the toplevel, next to the other class.

Masklinn
  • 34,759
  • 3
  • 38
  • 57
  • I moved PrivateUserFilter to the toplevel, next to the other class and get now the following error: TypeError: Can't instantiate abstract class PrivateUserFilter with abstract methods __call__ – Tom Mar 17 '21 at 13:03
  • That's an API misuse. According to the documentation for `BaseFilter`: "If you want to create your own filters create a class inheriting from either `MessageFilter` or `UpdateFilter` and implement a `filter()` method that returns a boolean: `True` if the message should be handled, `False` otherwise." – Masklinn Mar 17 '21 at 13:43
0

Change self.private_filter = PrivateUserFilter(allowed_user_id) to self.private_filter = self.PrivateUserFilter(allowed_user_id).

Edit: can also use TelegramBot instead of self.

Think of it like namespaces, you'll only be able to call the inner class if you reference the outer one.

LombardiD
  • 301
  • 1
  • 2
  • 9
  • thanks, that helped. I get now another error: TypeError: Can't instantiate abstract class PrivateUserFilter with abstract methods __call__ – Tom Mar 17 '21 at 13:09
  • Is the error pointing to somewhere else in the code? Have you defined other dunder methods? Is the error coming from: `self._prepare()` ? – LombardiD Mar 17 '21 at 13:14