Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8122827
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 6, 20262026-06-06T05:57:34+00:00 2026-06-06T05:57:34+00:00

I was looking at Python: Exception in the separated module works wrong which uses

  • 0

I was looking at Python: Exception in the separated module works wrong which uses a multi-purpose GnuLibError class to ‘stand in’ for a variety of different errors. Each sub-error has its own ID number and error format string.

I figured it would be better written as a hierarchy of Exception classes, and set out to do so:

class GNULibError(Exception):
    sub_exceptions = 0  # patched with dict of subclasses once subclasses are created
    err_num = 0
    err_format = None

    def __new__(cls, *args):
        print("new {}".format(cls)) # DEBUG
        if len(args) and args[0] in GNULibError.sub_exceptions:
            print("  factory -> {} {}".format(GNULibError.sub_exceptions[args[0]], args[1:])) # DEBUG
            return super(GNULibError, cls).__new__(GNULibError.sub_exceptions[args[0]], *(args[1:]))
        else:
            print("  plain {} {}".format(cls, args)) # DEBUG
            return super(GNULibError, cls).__new__(cls, *args)

    def __init__(self, *args):
        cls = type(self)
        print("init {} {}".format(cls, args)) # DEBUG
        self.args = args
        if cls.err_format is None:
            self.message = str(args)
        else:
            self.message = "[GNU Error {}] ".format(cls.err_num) + cls.err_format.format(*args)

    def __str__(self):
        return self.message

    def __repr__(self):
        return '{}{}'.format(type(self).__name__, self.args)

class GNULibError_Directory(GNULibError):
    err_num = 1
    err_format = "destination directory does not exist: {}"

class GNULibError_Config(GNULibError):
    err_num = 2
    err_format = "configure file does not exist: {}"

class GNULibError_Module(GNULibError):
    err_num = 3
    err_format = "selected module does not exist: {}"

class GNULibError_Cache(GNULibError):
    err_num = 4
    err_format = "{} is expected to contain gl_M4_BASE({})"

class GNULibError_Sourcebase(GNULibError):
    err_num = 5
    err_format = "missing sourcebase argument: {}"

class GNULibError_Docbase(GNULibError):
    err_num = 6
    err_format = "missing docbase argument: {}"

class GNULibError_Testbase(GNULibError):
    err_num = 7
    err_format = "missing testsbase argument: {}"

class GNULibError_Libname(GNULibError):
    err_num = 8
    err_format = "missing libname argument: {}"

# patch master class with subclass reference
# (TO DO: auto-detect all available subclasses instead of hardcoding them)
GNULibError.sub_exceptions = {
    1: GNULibError_Directory,
    2: GNULibError_Config,
    3: GNULibError_Module,
    4: GNULibError_Cache,
    5: GNULibError_Sourcebase,
    6: GNULibError_Docbase,
    7: GNULibError_Testbase,
    8: GNULibError_Libname
}

This starts out with GNULibError as a factory class – if you call it with an error number belonging to a recognized subclass, it returns an object belonging to that subclass, otherwise it returns itself as a default error type.

Based on this code, the following should be exactly equivalent (but aren’t):

e = GNULibError(3, 'missing.lib')
f = GNULibError_Module('missing.lib')

print e  # -> '[GNU Error 3] selected module does not exist: 3'
print f  # -> '[GNU Error 3] selected module does not exist: missing.lib'

I added some strategic print statements, and the error seems to be in GNULibError.__new__:

>>> e = GNULibError(3, 'missing.lib')

new <class '__main__.GNULibError'>
  factory -> <class '__main__.GNULibError_Module'> ('missing.lib',)  # good...
init <class '__main__.GNULibError_Module'> (3, 'missing.lib')        # NO!
                                            ^
                                           why?

I call the subclass constructor as subclass.__new__(*args[1:]) – this should drop the 3, the subclass type ID – and yet its __init__ is still getting the 3 anyway! How can I trim the argument list that gets passed to subclass.__init__?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-06T05:57:35+00:00Added an answer on June 6, 2026 at 5:57 am

    You cannot affect what is passed to __init__, as long as you’re doing it with a “factory class” like you have now that is returning subclasses of itself. The reason the “3” argument is still passed is because you are still returning an instance of GNULibError from __new__. By the time __new__ is called, it’s too late to decide what will be passed to __init__. As stated in the documentation (emphasis added):

    If __new__() returns an instance of cls, then the new instance’s __init__() method will be invoked like __init__(self[, ...]), where self is the new instance and the remaining arguments are the same as were passed to __new__().

    In other words, when you call GNULibError(3, 'missing.lib'), it’s too late — by calling the class with those arguments you have ensured that those are the arguments that will be passed to __init__. __new__ can return a different instance than you might otherwise get, but it can’t stop the normal initialization from happening.

    As suggested by @Ned Batchelder, you are better off using a factory function instead of a “factory class”, because a function doesn’t have this __new__/__init__ machinery and you can just return an instance of the class you want.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm looking into exception handling in python and a blog post I read differentiated
I am looking for a python module that will help me get rid of
Let's say I have a module which fails to import (there is an exception
Looking at Python modules and at code in the lib-dnyload directory in the Python
I am looking for python stubbing library. Something that could be used to create
I'm looking for a Python library that's suitable, with DOM access too. I don't
I am looking for a Python API (or a C API as I am
I am looking for a python SOAP 1.2 client but it seems that it
I'm looking for a python socket server framework - not to handle http, but
I'm looking for a Python IDE that can help me easily locate and manage

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.