Repository: ftao/python-ifcfg

Issue:
inet is not populated when returning the ip address with an arrow notation (-->)
Hi,

I have a case where the inet value was being returned ok in version 0.22, but fails to populate when using version 0.23:

```
utun3: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
	inet 10.11.11.72 --> 10.11.11.72 netmask 0xffffff00 
```

It occurs in macOS using an OpenVPN connection.  Will you please investigate a fix for this case?

Regards,

-A


Discussion:

Patch:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index bd0b837..ddfd967 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -8,6 +8,6 @@ repos:
     -   id: debug-statements
     -   id: end-of-file-fixer
 -   repo: https://github.com/pycqa/isort
-    rev: 5.10.1
+    rev: 5.12.0
     hooks:
       - id: isort
diff --git a/Makefile b/Makefile
index dfb2420..c5897c6 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,12 @@
-clean: clean-build clean-pyc clean-test
+all: build
+
+install: clean
+	python setup.py install
 
+build: clean
+	python setup.py build
+
+clean: clean-build clean-pyc clean-test
 
 clean-build: ## remove build artifacts
 	rm -fr build/
@@ -47,3 +54,6 @@ dist: clean  ## Generate wheels distribution
 	python setup.py bdist_wheel
 	python setup.py sdist
 	ls -l dist
+
+req:
+	pip install --requirement requirements_dev.txt
diff --git a/README.rst b/README.rst
index b414180..8ade301 100644
--- a/README.rst
+++ b/README.rst
@@ -128,6 +128,11 @@ Before commiting and opening PRs, ensure that you have pre-commit hooks running:
 Release notes
 -------------
 
+0.24
+----
+
+* add support for arrow notation inet #71
+
 0.23
 ____
 
diff --git a/requirements_dev.txt b/requirements_dev.txt
index 701f595..1014e61 100644
--- a/requirements_dev.txt
+++ b/requirements_dev.txt
@@ -1,3 +1,4 @@
-nose
 mock
+nose
 pre-commit
+tox
diff --git a/setup.py b/setup.py
index 841f0ae..5ee37b5 100644
--- a/setup.py
+++ b/setup.py
@@ -42,6 +42,9 @@ setup(
         'Programming Language :: Python :: 3.6',
         'Programming Language :: Python :: 3.7',
         'Programming Language :: Python :: 3.8',
+        'Programming Language :: Python :: 3.9',
+        'Programming Language :: Python :: 3.10',
+        'Programming Language :: Python :: 3.11',
         'Programming Language :: Python :: Implementation :: PyPy',
     ],
 )
diff --git a/src/ifcfg/__init__.py b/src/ifcfg/__init__.py
index a0e6b12..8a82d6c 100644
--- a/src/ifcfg/__init__.py
+++ b/src/ifcfg/__init__.py
@@ -6,7 +6,7 @@ import platform
 
 from . import parser, tools
 
-__version__ = "0.23"
+__version__ = "0.24"
 
 Log = tools.minimal_logger(__name__)
 
diff --git a/src/ifcfg/parser.py b/src/ifcfg/parser.py
index fd11ad1..93a0d55 100644
--- a/src/ifcfg/parser.py
+++ b/src/ifcfg/parser.py
@@ -20,7 +20,7 @@ DEVICE_PROPERTY_DEFAULTS = {
     'netmasks': 'LIST',
     'broadcast': None,
     'broadcasts': 'LIST',
-    'prefixlens': 'LIST',    
+    'prefixlens': 'LIST',
 }
 
 
@@ -242,7 +242,7 @@ class UnixParser(Parser):
     def get_patterns(cls):
         return [
             r'(?P<device>^[-a-zA-Z0-9:\.]+): flags=(?P<flags>.*) mtu (?P<mtu>\d+)',
-            r'.*inet\s+(?P<inet4>[\d\.]+)((\s+netmask\s)|\/)(?P<netmasks>[\w.]+)(\s+(brd|broadcast)\s(?P<broadcasts>[^\s]*))?.*',
+            r'.*inet\s+(?P<inet4>[\d\.]+)(\s+-->\s+(?P<_inet4>[\d\.]+))?((\s+netmask\s)|\/)(?P<netmasks>[\w.]+)((\s+(brd|broadcast)\s(?P<broadcasts>[^\s]*))?.*)?',
             r'.*inet6\s+(?P<inet6>[\d\:abcdef]+)(%\w+)?((\s+prefixlen\s+)|\/)(?P<prefixlens>\d+)',
             r'.*ether (?P<ether>[^\s]*).*',
         ]
diff --git a/tox.ini b/tox.ini
index a8d9c4c..910fad1 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,6 +1,6 @@
 [tox]
 # Ensure you add to .travis.yml if you add here, using `tox -l`
-envlist = py27,py34,py35,py36,py37,py38,lint
+envlist = py27,py34,py35,py36,py37,py38,py39,py310,py311,lint
 
 [travis]
 python =
@@ -10,6 +10,9 @@ python =
   3.6: py36
   3.7: py37
   3.8: py38
+  3.9: py39
+  3.10: py310
+  3.11: py311
 
 [testenv]
 
@@ -20,6 +23,9 @@ basepython =
      py36: python3.6
      py37: python3.7
      py38: python3.8
+     py39: python3.9
+     py310: python3.10
+     py311: python3.11
 
 commands =
     python --version


Test patch:
diff --git a/tests/ifconfig_out.py b/tests/ifconfig_out.py
index 76ffac5..3318930 100644
--- a/tests/ifconfig_out.py
+++ b/tests/ifconfig_out.py
@@ -195,6 +195,8 @@ en5: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
         nd6 options=281<PERFORMNUD,INSECURE,DAD>
         media: autoselect
         status: active
+utun3: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1400
+        inet 10.63.73.73 --> 10.63.73.73 netmask 0xffffffff
 """
 
 # See: https://github.com/ftao/python-ifcfg/issues/40
diff --git a/tests/ifconfig_tests.py b/tests/ifconfig_tests.py
index 6724380..4373f6b 100644
--- a/tests/ifconfig_tests.py
+++ b/tests/ifconfig_tests.py
@@ -1,9 +1,10 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
+from nose.tools import eq_, ok_, raises
+
 import ifcfg
 from ifcfg.parser import LinuxParser, NullParser
-from nose.tools import eq_, ok_, raises
 
 from . import ifconfig_out
 from .base import IfcfgTestCase
@@ -107,11 +108,13 @@ class IfcfgTestCase(IfcfgTestCase):
         ifcfg.Parser = ifcfg.get_parser_class()
         parser = ifcfg.get_parser(ifconfig=ifconfig_out.MACOSX2)
         interfaces = parser.interfaces
-        self.assertEqual(len(interfaces.keys()), 9)
+        self.assertEqual(len(interfaces.keys()), 10)
         eq_(interfaces['lo0']['inet'], '127.0.0.1')
         eq_(interfaces['lo0']['inet4'], ['127.0.0.1', '127.0.1.99'])
         eq_(interfaces['lo0']['netmask'], '255.0.0.0')
         eq_(interfaces['lo0']['netmasks'], ['255.0.0.0', '255.0.0.0'])
+        eq_(interfaces['utun3']['inet'], '10.63.73.73')
+        eq_(interfaces['utun3']['netmask'], '255.255.255.255')
 
     def test_default_interface(self):
         ifcfg.distro = 'Linux'