Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AttributeError: can't set attribute #2

Closed
akr8986 opened this issue Feb 1, 2017 · 11 comments
Closed

AttributeError: can't set attribute #2

akr8986 opened this issue Feb 1, 2017 · 11 comments
Milestone

Comments

@akr8986
Copy link

akr8986 commented Feb 1, 2017

I am using python version 3.5

$ python --version
Python 3.5.1

I am facing the below error when i am importing the ifparser package i am seeing an attribute error:

In [1]: from ifparser import Ifcfg
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-1-e4742fe46d86> in <module>()
----> 1 from ifparser import Ifcfg

/*****/site-packages/ifparser/__init__.py in <module>()
----> 1 from .ifconfig import Ifcfg, Interface
      2
      3 __title__ = 'ifparser'
      4 __version__ = '0.5.0'
      5 __author__ = 'Sanket Sudake'

/******/site-packages/ifparser/ifconfig.py in <module>()
     51
     52
---> 53 class Ifcfg(object):
     54     scanner = Scanner([
     55         ('process_interface', r"(?P<interface>^[a-zA-Z0-9:-]+)\s+"

/******/site-packages/ifparser/ifconfig.py in Ifcfg()
     67          ".*?mtu (?P<mtu>[0-9]+).*"),
     68         ('process_ignore', r"(Ifconfig|Infiniband|Because)\s.*"),
---> 69         ('process_ignore', r"\s+.*"),
     70     ])
     71

/***********/site-packages/ifparser/re_scan.py in __init__(self, rules, flags)
     99         pattern = Pattern()
    100         pattern.flags = flags
--> 101         pattern.groups = len(rules) + 1
    102         _og = pattern.opengroup
    103         pattern.opengroup = lambda n: _og(n and '%s\x00%s' % (name, n) or n)

AttributeError: can't set attribute
@sanketsudake
Copy link
Owner

@akr8986 Currently python 3 support is not completely added. I am planning to add it.

@sanketsudake sanketsudake added this to the python3 milestone Feb 1, 2017
@akr8986
Copy link
Author

akr8986 commented Feb 2, 2017

The issue seems to be with re_scan.py file.. The pattern object doesnt allow to set the value of groups variable..It auto-populates the variable value during execution.. i tried removing the line and executing the script.. it works fine... Not sure if its the right fix though!!

@sanketsudake
Copy link
Owner

I have tried it earlier. Test didn't pass. I am exploring it. Let me know if all tests pass with your solution.

@akr8986
Copy link
Author

akr8986 commented Feb 9, 2017

GIT DIFF:

git diff ifparser/re_scan.py
diff --git a/ifparser/re_scan.py b/ifparser/re_scan.py
index 4085365..ce9ba7f 100644
--- a/ifparser/re_scan.py
+++ b/ifparser/re_scan.py
@@ -98,7 +98,6 @@ class Scanner(object):
     def __init__(self, rules, flags=0):
         pattern = Pattern()
         pattern.flags = flags
-        pattern.groups = len(rules) + 1
         _og = pattern.opengroup
         pattern.opengroup = lambda n: _og(n and '%s\x00%s' % (name, n) or n)

UT Result:

Results (1.82s):
2 passed
5 failed

     - /phaedrus/home/abaskaran/Py3rdParty/ifconfig-parser/ifparser/ifconfig.py:136: KeyError: 'vcsbr'
     - /phaedrus/home/abaskaran/Py3rdParty/ifconfig-parser/ifparser/ifconfig.py:136: KeyError: 'p1p1'
     - /phaedrus/home/abaskaran/Py3rdParty/ifconfig-parser/tests/test_ifcfg_parser.py:77: IndexError: list index out of range
     - /phaedrus/home/abaskaran/Py3rdParty/ifconfig-parser/tests/test_ifcfg_parser.py:71: AssertionError: dict_keys(['lo        Link encap:Local Lo[128 chars]  ']) != ['lo', 'docker0', 'eth0']
     - /phaedrus/home/abaskaran/Py3rdParty/ifconfig-parser/tests/test_ifcfg_parser.py:97: AssertionError: dict_keys(['lo', 'eth0', 'wlan0']) != ['lo', 'wlan0', 'eth0']

The last assert seems wrong to me.. since both of them have same elements but only in a different order. am not sure about the other errors!

@sanketsudake
Copy link
Owner

Thanks for pointing out and debugging. I have updated interfaces property to return sorted list instead of directly returning from dictionary keys list. With it 2 testcases are fixed. I also focusing on rest to include python 3 support. Temporarily I am setting pattern groups len for python 2 only.

The last assert seems wrong to me.. since both of them have same elements but only in a different order. am not sure about the other errors!

@akr8986
Copy link
Author

akr8986 commented Feb 20, 2017

There are few more things for which support has to be added..

  1. i see some more flags for the interfaces in my machines : 'PROMISC', 'NOARP', 'SIMPLEX',. These flags have to be added in the _flags forzenset.

  2. Support for IPV6:

     inet 10.31.96.29  netmask 255.255.255.0  broadcast 10.31.96.255
     inet6 fe80::20c:29ff:fe91:a979  prefixlen 64  scopeid 0x20<link>
     ether <.........>  txqueuelen 1000  (Ethernet)
    
  3. I have a ifconfig ouput where the RX and TX bytes are not parsed from the output.

    RX packets 198237  bytes 283303360 (270.1 MiB)
    RX errors 0  dropped 0  overruns 0  frame 0
    TX packets 21948  bytes 2979032 (2.8 MiB)
    TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    The current regExp doesnt take care of packets and bytes info present in the same line..
    
  4. A format of ifconfig doesnt seem to be handled:

eth0      Link encap:Ethernet  HWaddr <dummy_val>
          inet addr:10.31.96.30  Bcast:10.31.96.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fecc:1ede/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:330418 errors:0 dropped:0 overruns:0 frame:0
          TX packets:38340 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:464157333 (442.6 MiB)  TX bytes:6906511 (6.5 MiB)

eth1      Link encap:Ethernet  HWaddr <dummy_val>
          inet addr:2.0.0.3  Bcast:2.255.255.255  Mask:255.0.0.0
          inet6 addr: fe80::20c:29ff:fecc:1ee8/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:28041 errors:0 dropped:0 overruns:0 frame:0
          TX packets:37411 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:7572430 (7.2 MiB)  TX bytes:8171676 (7.7 MiB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:3617825 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3617825 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:778195827 (742.1 MiB)  TX bytes:778195827 (742.1 MiB)

@akr8986
Copy link
Author

akr8986 commented Feb 22, 2017

For inet6 i defined a new method:

    def process_ipV6(self, group, groupdict, matched_str):
        if 'inet6 addr:' in matched_str:
            splitStr = matched_str.strip().lower().replace('inet6 addr:',
                                                           'ipv6').split()
            setattr(self._interfaces[self.curr_interface], 'ipv6', splitStr[1])
        else:
            map_dict = {'inet6': 'ipv6', 'prefixlen': 'prefix', 'scopeid': 'scope'}
            kv = iter(matched_str.split())
            for k, v in zip(kv, kv):
                groupdict[map_dict[k]] = v
            self.set_curr_interface_attr(groupdict)

For other two issues i did not see any other way other than creating new methods and new set of RegExp..

After modification my RegExp list fed to Scanner class is below:

    scanner = Scanner([
        ('process_interface', r"(?P<interface>^[a-zA-Z0-9:-]+)\s+"
         "Link encap:(?P<itype>[A-Za-z]+)"
         "((?:Loopback)|(?:HWaddr\s(?P<hwaddr>[0-9A-Fa-f:]+))).*"),
        ('process_any', r"\s+ether\s(?P<hwaddr>[0-9A-Fa-f:]+).*"),
        ('process_ip', r"\s+inet[\s:].*"),
        ('process_ipV6', r"\s+inet6[\s:].*"),
        ('process_mtu', r"\s+(?P<states>[A-Z\s]+\s*)+MTU:(?P<mtu>[0-9]+).*"),
        ('process_any', r"\s+RX bytes:(?P<rxbytes>\d+).*?"),
        ('process_any', r"\s+TX bytes:(?P<txbytes>\d+).*?"),
        ('process_any', r"\s+RX packets:(?P<rxpkts>\d+).*"),
        ('process_any', r"\s+TX packets:(?P<txpkts>\d+).*"),
        ('process_RxTx', r"\s+RX packets\s(?P<rxpkts>\d+)\s+bytes\s(?P<rxbytes>\d+).*"),
        ('process_RxTx', r"\s+TX packets\s(?P<txpkts>\d+)\s+bytes\s(?P<txbytes>\d+).*"),
        ('process_interface2',
         r"(?P<interface>^[a-zA-Z0-9-]+).*?<(?P<states>[A-Z,]+\s*)>"
         ".*?mtu (?P<mtu>[0-9]+).*"),
        ('process_interface3', r"(?P<interface>^[a-zA-Z0-9:-]+)\s+"
         "Link encap:(?P<itype>.*)$"),
        ('process_ignore', r"(Ifconfig|Infiniband|Because)\s.*"),
        ('process_ignore', r"\s+.*"),
    ])

process_RxTx method is simple..


    def process_RxTx(self, group, groupdict, matched_str):
        self.set_curr_interface_attr(groupdict)

and process_interface3 is just a copy of process_interface2.. i had to create a new method since Scanner class was cribbing about having same name (which is our func ptr)..

@sanketsudake
Copy link
Owner

  1. i see some more flags for the interfaces in my machines : 'PROMISC', 'NOARP', 'SIMPLEX',. These flags have to be added in the _flags forzenset.

Mostly I have added things as I found them, I havn't referred ifconfig(net-tools) source as such. Might have missed these flags. Of course, we can add as we explore.

  1. Support for IPV6:

     inet 10.31.96.29  netmask 255.255.255.0  broadcast 10.31.96.255
     inet6 fe80::20c:29ff:fe91:a979  prefixlen 64  scopeid 0x20<link>
     ether <.........>  txqueuelen 1000  (Ethernet)
    

As you have worked out we can add ipv6 support. Though will need to add testcases around this.

  1. I have a ifconfig ouput where the RX and TX bytes are not parsed from the output.

    RX packets 198237  bytes 283303360 (270.1 MiB)
    RX errors 0  dropped 0  overruns 0  frame 0
    TX packets 21948  bytes 2979032 (2.8 MiB)
    TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    The current regExp doesnt take care of packets and bytes info present in the same line..
    

We can merge following regexes as there is only difference of optional ':' character.

        ('process_any', r"\s+RX packets:(?P<rxpkts>\d+).*"),
        ('process_any', r"\s+TX packets:(?P<txpkts>\d+).*"),
        ('process_RxTx', r"\s+RX packets\s(?P<rxpkts>\d+)\s+bytes\s(?P<rxbytes>\d+).*"),
        ('process_RxTx', r"\s+TX packets\s(?P<txpkts>\d+)\s+bytes\s(?P<txbytes>\d+).*"),

Also you don't need to define separate process_RxTx method as it does same work as process_any, so you can keep process_any as handler for regex.

  1. A format of ifconfig doesn't seem to be handled:

Can you share txt file of your output (may be filtered) ? Seems like process_interface3 is subset of process_interface . Might need few tweaks in process_interface

    ('process_interface3', r"(?P<interface>^[a-zA-Z0-9:-]+)\s+"
     "Link encap:(?P<itype>.*)$"),

Thanks for all great findings, I would really appreciate if you raise pull request for your changes and I can also have deep look at changes.

@akr8986
Copy link
Author

akr8986 commented Feb 27, 2017

Hi,

process_interface3 is just a copy of process_interface method..

scanner class was throwing an error if i tried to reuse the same method. I dint debug further why..

And the issue (which is solved by process_interface3) can be reproduced with the ifconfig output i have given above..

@sanketsudake
Copy link
Owner

@akr8986 Can you please create pull request with your changes ? We will take this forward from there.

@sanketsudake
Copy link
Owner

Related #15 . Closing this for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants