# Buggy code
def get_memory_facts(self, collected_facts=None):
    memory_facts = {}
    collected_facts = collected_facts or {}

    pagesize = 4096
    rc, out, err = self.module.run_command(
        "/usr/bin/vmstat | tail -1", use_unsafe_shell=True
    )
    data = int(re.sub(" +", " ", out).split(" ")[5].strip())
    memory_facts["memfree_mb"] = pagesize * data // 1024 // 1024
    if collected_facts.get("ansible_architecture") == "9000/800":
        try:
            rc, out, err = self.module.run_command(
                "grep Physical /var/adm/syslog/syslog.log"
            )
            data = re.search(".*Physical: ([0-9]*) Kbytes.*", out).groups()[0].strip()
            memory_facts["memtotal_mb"] = int(data) // 1024
        except AttributeError:
            # For systems where memory details aren't sent to syslog or the log has rotated, use parsed
            # adb output. Unfortunately /dev/kmem doesn't have world-read, so this only works as root.
            if os.access("/dev/kmem", os.R_OK):
                rc, out, err = self.module.run_command(
                    "echo 'phys_mem_pages/D' | adb -k /stand/vmunix /dev/kmem | tail -1 | awk '{print $2}'",
                    use_unsafe_shell=True,
                )
                if not err:
                    data = out
                    memory_facts["memtotal_mb"] = int(data) / 256
    else:
        rc, out, err = self.module.run_command(
            "/usr/contrib/bin/machinfo | grep Memory", use_unsafe_shell=True
        )
        data = re.search(r"Memory[\ :=]*([0-9]*).*MB.*", out).groups()[0].strip()
        memory_facts["memtotal_mb"] = int(data)
    rc, out, err = self.module.run_command("/usr/sbin/swapinfo -m -d -f -q")
    memory_facts["swaptotal_mb"] = int(out.strip())
    rc, out, err = self.module.run_command(
        "/usr/sbin/swapinfo -m -d -f | egrep '^dev|^fs'", use_unsafe_shell=True
    )
    swap = 0
    for line in out.strip().splitlines():
        swap += int(re.sub(" +", " ", line).split(" ")[3].strip())
    memory_facts["swapfree_mb"] = swap

    return memory_facts


# Traceback (nAttributeError)
Loading callback plugin minimal of type stdout, v2.0 from /usr/lib/python2.7/site-packages/ansible/plugins/callback/__init__.pyc
META: ran handlers
Using module file /usr/lib/python2.7/site-packages/ansible/modules/system/setup.py
<xxx.xxx.xxx.xxx> ESTABLISH CONNECTION FOR USER: root on PORT 22 TO xxx.xxx.xxx.xxx
<xxx.xxx.xxx.xxx> EXEC /bin/sh -c '( umask 77 &amp;&amp; mkdir -p "` echo $HOME/.ansible/tmp/ansible-tmp-1508496494.76-29371413675763 `" &amp;&amp; echo ansible-tmp-1508496494.76-29371413675763="` echo $HOME/.ansible/tmp/ansible-tmp-1508496494.76-29371413675763 `" ) &amp;&amp; sleep 0'
<xxx.xxx.xxx.xxx> PUT /tmp/tmpXmIMND TO //.ansible/tmp/ansible-tmp-1508496494.76-29371413675763/setup.py
<xxx.xxx.xxx.xxx> EXEC /bin/sh -c 'chmod u+x //.ansible/tmp/ansible-tmp-1508496494.76-29371413675763/ //.ansible/tmp/ansible-tmp-1508496494.76-29371413675763/setup.py &amp;&amp; sleep 0'
<xxx.xxx.xxx.xxx> EXEC /bin/sh -c '/opt/PBpython/bin/python //.ansible/tmp/ansible-tmp-1508496494.76-29371413675763/setup.py; rm -rf "//.ansible/tmp/ansible-tmp-1508496494.76-29371413675763/" > /dev/null 2>&amp;1 &amp;&amp; sleep 0'
HOSTNAME-REDACTED| FAILED! => {
"changed": false,
"failed": true,
"module_stderr": "",
"module_stdout": "Traceback (most recent call last):\r\n  File \"/tmp/ansible_81XLGz/ansible_module_setup.py\", line 139, in <module>\r\n    main()\r\n  File \"/tmp/ansible_81XLGz/ansible_module_setup.py\", line 131, in main\r\n    data = get_all_facts(module)\r\n  File \"/tmp/ansible_81XLGz/ansible_modlib.zip/ansible/module_utils/facts.py\", line 3939, in get_all_facts\r\n  File \"/tmp/ansible_81XLGz/ansible_modlib.zip/ansible/module_utils/facts.py\", line 3882, in ansible_facts\r\n  File \"/tmp/ansible_81XLGz/ansible_modlib.zip/ansible/module_utils/facts.py\", line 2246, in populate\r\n  File \"/tmp/ansible_81XLGz/ansible_modlib.zip/ansible/module_utils/facts.py\", line 2315, in get_memory_facts\r\nAttributeError: 'NoneType' object has no attribute 'groups'\r\n",
"msg": "MODULE FAILURE",
"rc": 0
}

# Fixed code
def get_memory_facts(self, collected_facts=None):
    memory_facts = {}
    collected_facts = collected_facts or {}

    pagesize = 4096
    rc, out, err = self.module.run_command(
        "/usr/bin/vmstat | tail -1", use_unsafe_shell=True
    )
    data = int(re.sub(" +", " ", out).split(" ")[5].strip())
    memory_facts["memfree_mb"] = pagesize * data // 1024 // 1024
    if collected_facts.get("ansible_architecture") in ["9000/800", "9000/785"]:
        try:
            rc, out, err = self.module.run_command(
                "grep Physical /var/adm/syslog/syslog.log"
            )
            data = re.search(".*Physical: ([0-9]*) Kbytes.*", out).groups()[0].strip()
            memory_facts["memtotal_mb"] = int(data) // 1024
        except AttributeError:
            # For systems where memory details aren't sent to syslog or the log has rotated, use parsed
            # adb output. Unfortunately /dev/kmem doesn't have world-read, so this only works as root.
            if os.access("/dev/kmem", os.R_OK):
                rc, out, err = self.module.run_command(
                    "echo 'phys_mem_pages/D' | adb -k /stand/vmunix /dev/kmem | tail -1 | awk '{print $2}'",
                    use_unsafe_shell=True,
                )
                if not err:
                    data = out
                    memory_facts["memtotal_mb"] = int(data) / 256
    else:
        rc, out, err = self.module.run_command(
            "/usr/contrib/bin/machinfo | grep Memory", use_unsafe_shell=True
        )
        data = re.search(r"Memory[\ :=]*([0-9]*).*MB.*", out).groups()[0].strip()
        memory_facts["memtotal_mb"] = int(data)
    rc, out, err = self.module.run_command("/usr/sbin/swapinfo -m -d -f -q")
    memory_facts["swaptotal_mb"] = int(out.strip())
    rc, out, err = self.module.run_command(
        "/usr/sbin/swapinfo -m -d -f | egrep '^dev|^fs'", use_unsafe_shell=True
    )
    swap = 0
    for line in out.strip().splitlines():
        swap += int(re.sub(" +", " ", line).split(" ")[3].strip())
    memory_facts["swapfree_mb"] = swap

    return memory_facts