views:

144

answers:

2

Hi all,

I have a basic Monostate with Python 2.6.

class Borg(object):
    __shared_state = {}
    def __new__(cls, *args, **kwargs):
        self = object.__new__(cls, *args, **kwargs)
        self.__dict__ = cls.__shared_state
        return self

    def __init__(self, *args, **kwargs):
        noSend = kwargs.get("noSend", False)
        reportLevel = kwargs.get("reportLevel", 30)
        reportMethods = kwargs.get("reportMethods", "BaseReport")
        contacts= kwargs.get("contacts", None)

a = Borg(contacts="Foo", noSend="Bar", )

Which happily gives me the following Deprecation warning..

untitled:4: DeprecationWarning: object.__new__() takes no parameters
  self = object.__new__(cls, *args, **kwargs)

After a bit of googling I find this is attached to Bug #1683368. What I can't figure out is what this means. It's complaining about the following line

self = object.__new__(cls, *args, **kwargs)

Which appears to be OK. Can someone explain in laymens terms why this is a problem. I understand that "this is inconsistent with other built-ins, like list" but I'm not sure I understand why. Would someone explain this show me the right way to do it?

Thanks

+1  A: 

The warning comes from the fact that __new__() can HAVE args, but since they're ignored everywhere, passing args (other than cls) to it causes the warning. It's not actually (currently) an error to pass the extra args, but they have no effect.

In py3k it will become an error to pass the args.

Paul McMillan
I'm failing to see how they are ignored? Take out *args and **kwargs from new and it'll bomb because they are needed by __init__ which is expecting them.You last statement is the one I'm trying to prevent :-) I want it to work in 3k.
rh0dium
I can't argue with the language designers. If they say "new doesn't take any arguments", I make it take no arguments. `__init__` and `__new__` function similarly, perhaps your use case should be using init instead of new.
Paul McMillan
A: 

See python-singleton-object-instantiation, and note Alex Martelli's singleton example:

class Singleton(object):

    __instance = None

    def __new__(cls):
        if cls.__instance == None:
            __instance = type.__new__(cls)
            __instance.name = "The one"
        return __instance

The __new__ deprecation question was answered by Guido:

The message means just what it says. :-) There's no point in calling object.new() with more than a class parameter, and any code that did so was just dumping those args into a black hole.

The only time when it makes sense for object.new() to ignore extra arguments is when it's not being overridden, but init is being overridden -- then you have a completely default new and the checking of constructor arguments is relegated to init.

The purpose of all this is to catch the error in a call like object(42) which (again) passes an argument that is not used. This is often a symptom of a bug in your program.

--Guido

gimel
That's a singleton (aka highlander) is not a borg (monostate). I have been [schooled][1] on that already. I also have ready Guido's comments but as I said earlier if your init has the requirements of *args **kwargs then __new__ would also require them? Right??[1]: http://stackoverflow.com/questions/1575680/ensure-that-only-one-instance-of-a-class-gets-run
rh0dium
Sorry the bold and link got messed up..
rh0dium
Guido explicitly says that only __init__ is required to check constructor arguments.
gimel