Subclassing ConfigParser

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Greg Krohn

    Subclassing ConfigParser

    I'm trying to subclass ConfigParser so I can use a custom __read method (the
    custom format doesn't conform to RFC 822) when needed. Needless to say, it's
    not working as expected.

    In the following code, I bind __read_ini to __read and override __read so it
    can choose between __read_ini and __read_custom. But it seems that
    __read_custom never gets called when I expect it to aways be called. I have
    a feeling this has to do with me not entirely understanding magic atributes
    and name mangling. Anyone have ideas?


    greg



    from ConfigParser import ConfigParser

    class CustomConfigPar ser(ConfigParse r):
    def __init__(self, defaults=None):
    ConfigParser.__ init__(self, defaults)

    #Replace the normal __read with my custom __read
    #while keeping the normal one around if I need it
    self.__read_ini = ConfigParser._C onfigParser__re ad
    ConfigParser._C onfigParser__re ad = self.__read

    def __read(self, fp, fpname):
    #Eventually this will decide between __read_custom
    #and __read_ini, etc.
    self.__read_cus tom(fp, fpname)

    def __read_custom(s elf, fp, fpname):
    print "__read_cus tom" #This never gets printed.

    cp = CustomConfigPar ser()
    cp.read('config .ini')
    print cp.sections()


  • Michael Amrhein

    #2
    Re: Subclassing ConfigParser

    Greg Krohn schrieb:
    [color=blue]
    > I'm trying to subclass ConfigParser so I can use a custom __read method (the
    > custom format doesn't conform to RFC 822) when needed. Needless to say, it's
    > not working as expected.
    >
    > In the following code, I bind __read_ini to __read and override __read so it
    > can choose between __read_ini and __read_custom. But it seems that
    > __read_custom never gets called when I expect it to aways be called. I have
    > a feeling this has to do with me not entirely understanding magic atributes
    > and name mangling. Anyone have ideas?
    >
    >
    > greg
    >
    >
    >
    > from ConfigParser import ConfigParser
    >
    > class CustomConfigPar ser(ConfigParse r):
    > def __init__(self, defaults=None):
    > ConfigParser.__ init__(self, defaults)
    >
    > #Replace the normal __read with my custom __read
    > #while keeping the normal one around if I need it
    > self.__read_ini = ConfigParser._C onfigParser__re ad
    > ConfigParser._C onfigParser__re ad = self.__read
    >
    > def __read(self, fp, fpname):
    > #Eventually this will decide between __read_custom
    > #and __read_ini, etc.
    > self.__read_cus tom(fp, fpname)
    >
    > def __read_custom(s elf, fp, fpname):
    > print "__read_cus tom" #This never gets printed.
    >
    > cp = CustomConfigPar ser()
    > cp.read('config .ini')
    > print cp.sections()
    >
    >[/color]
    Hi Greg,
    are you sure you have a file 'config.ini' in your current working
    directory? ConfigParser is silently ignoring files which cannot be
    opened, so that _read is not called!

    BTW, you did not mention the Python version you are using. In Python 2.3
    the method you overwrite is named '_read', not '__read' (so there is no
    name mangling). This is one drawback of overwriting "private" methods,
    when the author renames or removes them, your code is broken.

    Anyway, your method of overwriting the method is a bit complicated . You
    can do it much easier: just overwrite _read and call the original method
    when appropriate:

    class CustomConfigPar ser(ConfigParse r):
    def __init__(self, defaults=None):
    ConfigParser.__ init__(self, defaults)
    def _read(self, fp, fpname):
    if ... # your criteria for custom ini
    then return self._read_cust om(fp, fpname)
    else return ConfigParser._r ead(self, fp, fpname)

    def _read_custom(se lf, fp, fpname):
    ...

    Michael

    Comment

    • Michael Amrhein

      #3
      Re: Subclassing ConfigParser

      Greg Krohn schrieb:
      [color=blue]
      > I'm trying to subclass ConfigParser so I can use a custom __read method (the
      > custom format doesn't conform to RFC 822) when needed. Needless to say, it's
      > not working as expected.
      >
      > In the following code, I bind __read_ini to __read and override __read so it
      > can choose between __read_ini and __read_custom. But it seems that
      > __read_custom never gets called when I expect it to aways be called. I have
      > a feeling this has to do with me not entirely understanding magic atributes
      > and name mangling. Anyone have ideas?
      >
      >
      > greg
      >
      >
      >
      > from ConfigParser import ConfigParser
      >
      > class CustomConfigPar ser(ConfigParse r):
      > def __init__(self, defaults=None):
      > ConfigParser.__ init__(self, defaults)
      >
      > #Replace the normal __read with my custom __read
      > #while keeping the normal one around if I need it
      > self.__read_ini = ConfigParser._C onfigParser__re ad
      > ConfigParser._C onfigParser__re ad = self.__read
      >
      > def __read(self, fp, fpname):
      > #Eventually this will decide between __read_custom
      > #and __read_ini, etc.
      > self.__read_cus tom(fp, fpname)
      >
      > def __read_custom(s elf, fp, fpname):
      > print "__read_cus tom" #This never gets printed.
      >
      > cp = CustomConfigPar ser()
      > cp.read('config .ini')
      > print cp.sections()
      >
      >[/color]
      Hi Greg,
      are you sure you have a file 'config.ini' in your current working
      directory? ConfigParser is silently ignoring files which cannot be
      opened, so that _read is not called!

      BTW, you did not mention the Python version you are using. In Python 2.3
      the method you overwrite is named '_read', not '__read' (so there is no
      name mangling). This is one drawback of overwriting "private" methods,
      when the author renames or removes them, your code is broken.

      Anyway, your method of overwriting the method is a bit complicated . You
      can do it much easier: just overwrite _read and call the original method
      when appropriate:

      class CustomConfigPar ser(ConfigParse r):
      def __init__(self, defaults=None):
      ConfigParser.__ init__(self, defaults)
      def _read(self, fp, fpname):
      if ... # your criteria for custom ini
      then return self._read_cust om(fp, fpname)
      else return ConfigParser._r ead(self, fp, fpname)

      def _read_custom(se lf, fp, fpname):
      ...

      Michael

      Comment

      • Greg Krohn

        #4
        Re: Subclassing ConfigParser


        "Michael Amrhein" <michael.amrhei [email protected]> wrote in message
        news:3F4621AC.8 [email protected]...[color=blue]
        > Hi Greg,
        > are you sure you have a file 'config.ini' in your current working
        > directory? ConfigParser is silently ignoring files which cannot be
        > opened, so that _read is not called![/color]

        I was getting a ParsingError that showed the line it was choking on, so I
        know it was finding the file.
        [color=blue]
        >
        > BTW, you did not mention the Python version you are using. In Python 2.3
        > the method you overwrite is named '_read', not '__read' (so there is no
        > name mangling). This is one drawback of overwriting "private" methods,
        > when the author renames or removes them, your code is broken.[/color]

        I _was_ using ActivePython 2.2 (2.3 isn't out yet). I downloaded the 2.3
        regular distro last night because I read ConfigParser was cleaned up, but I
        haven't had time to mess around with it much.
        [color=blue]
        > Anyway, your method of overwriting the method is a bit complicated . You
        > can do it much easier: just overwrite _read and call the original method
        > when appropriate:
        >
        > class CustomConfigPar ser(ConfigParse r):
        > def __init__(self, defaults=None):
        > ConfigParser.__ init__(self, defaults)
        > def _read(self, fp, fpname):
        > if ... # your criteria for custom ini
        > then return self._read_cust om(fp, fpname)
        > else return ConfigParser._r ead(self, fp, fpname)
        >
        > def _read_custom(se lf, fp, fpname):
        > ...
        >
        > Michael[/color]

        Yes, this is great! Everything is working as expected now. Originally I was
        expecting code like yours to work in 2.2 and when it didn't I tried all
        sorts of elaborate hacks. What a mess. Thank you very much for your reply.

        greg


        Comment

        Working...