From 7f8675ca87ef8c3dca53bf752a53d2480c3e5083 Mon Sep 17 00:00:00 2001
From: Hugo Lefeuvre <hle@debian.org>
Date: Sat, 20 Jul 2019 20:55:07 -0300
Subject: [PATCH] New upstream version 5.0.0

---
 ChangeLog                                    |    6 +
 LICENSE                                      |    2 +-
 PKG-INFO                                     |    2 +-
 cpuinfo/cpuinfo.py                           | 1003 +++++++++---------
 py_cpuinfo.egg-info/PKG-INFO                 |    2 +-
 py_cpuinfo.egg-info/SOURCES.txt              |    1 +
 setup.py                                     |    4 +-
 test_suite.py                                |    6 +-
 tests/helpers.py                             |    5 +-
 tests/test_cli.py                            |   47 +
 tests/test_example.py                        |    2 +-
 tests/test_free_bsd_11_x86_64.py             |    4 +-
 tests/test_haiku_x86_32.py                   |    4 +-
 tests/test_haiku_x86_64.py                   |    4 +-
 tests/test_invalid_cpu.py                    |    2 +-
 tests/test_linux_aarch64_64.py               |    4 +-
 tests/test_linux_beagle_bone_arm.py          |    4 +-
 tests/test_linux_debian_8_5_x86_64.py        |    4 +-
 tests/test_linux_debian_8_7_1_ppc64le.py     |    4 +-
 tests/test_linux_debian_8_x86_64.py          |    4 +-
 tests/test_linux_fedora_24_ppc64le.py        |    4 +-
 tests/test_linux_fedora_24_x86_64.py         |    4 +-
 tests/test_linux_gentoo_2_2_x86_64.py        |    4 +-
 tests/test_linux_odroid_c2_aarch64.py        |    4 +-
 tests/test_linux_odroid_xu3_arm_32.py        |    4 +-
 tests/test_linux_raspberry_pi_model_b_arm.py |    4 +-
 tests/test_linux_rhel_7_3_ppc64le.py         |    4 +-
 tests/test_linux_ubuntu_16_04_x86_64.py      |    4 +-
 tests/test_osx_10_12_x86_64.py               |    4 +-
 tests/test_osx_10_9_x86_64.py                |    4 +-
 tests/test_parse_cpu_string.py               |   12 +-
 tests/test_parse_errors.py                   |    2 +-
 tests/test_pcbsd_10_x86_64.py                |    4 +-
 tests/test_solaris_11_x86_32.py              |    4 +-
 tests/test_windows_10_x86_64.py              |    4 +-
 tests/test_windows_8_x86_64.py               |    4 +-
 36 files changed, 644 insertions(+), 540 deletions(-)
 create mode 100644 tests/test_cli.py

diff --git a/ChangeLog b/ChangeLog
index e000a44..8c5b05b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+03/20/2019 Release 5.0.0
+	* Fixed Bug #117: Remove PyInstaller hacks
+	* Fixed Bug #108: Client script runs multiple times without __main__
+	* Fixed Bug #113: Add option to return results in json
+	* Fixed Bug #110: Always tries to run wmic in get_system_info.py
+
 04/01/2018 Release 4.0.0
 	* Fixed Bug #80: Broken when using Pyinstaller
 	* Fixed Bug #77: Get L1, L2, and L3 cache info from lscpu
diff --git a/LICENSE b/LICENSE
index 7a1e922..3f2a5ae 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
 The MIT License (MIT)
 
-Copyright (c) 2014-2018 Matthew Brennan Jones <matthew.brennan.jones@gmail.com>
+Copyright (c) 2014-2019 Matthew Brennan Jones <matthew.brennan.jones@gmail.com>
 
 Permission is hereby granted, free of charge, to any person obtaining a copy of
 this software and associated documentation files (the "Software"), to deal in
diff --git a/PKG-INFO b/PKG-INFO
index 17c18f8..8495ee5 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: py-cpuinfo
-Version: 4.0.0
+Version: 5.0.0
 Summary: Get CPU info with pure Python 2 & 3
 Home-page: https://github.com/workhorsy/py-cpuinfo
 Author: Matthew Brennan Jones
diff --git a/cpuinfo/cpuinfo.py b/cpuinfo/cpuinfo.py
index 10be231..b8fc7e5 100644
--- a/cpuinfo/cpuinfo.py
+++ b/cpuinfo/cpuinfo.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
-# Copyright (c) 2014-2018, Matthew Brennan Jones <matthew.brennan.jones@gmail.com>
+# Copyright (c) 2014-2019, Matthew Brennan Jones <matthew.brennan.jones@gmail.com>
 # Py-cpuinfo gets CPU info with pure Python 2 & 3
 # It uses the MIT License
 # It is hosted at: https://github.com/workhorsy/py-cpuinfo
@@ -25,18 +25,12 @@
 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-CPUINFO_VERSION = (4, 0, 0)
+CPUINFO_VERSION = (5, 0, 0)
 
 import os, sys
-import glob
-import re
-import time
 import platform
 import multiprocessing
 import ctypes
-import pickle
-import base64
-import subprocess
 
 try:
 	import _winreg as winreg
@@ -46,40 +40,8 @@ except ImportError as err:
 	except ImportError as err:
 		pass
 
-PY2 = sys.version_info[0] == 2
+IS_PY2 = sys.version_info[0] == 2
 
-# Load hacks for Windows
-if platform.system().lower() == 'windows':
-	# Monkey patch multiprocessing's Popen to fork properly on Windows Pyinstaller
-	# https://github.com/pyinstaller/pyinstaller/wiki/Recipe-Multiprocessing
-	try:
-		import multiprocessing.popen_spawn_win32 as forking
-	except ImportError as err:
-		try:
-			import multiprocessing.popen_fork as forking
-		except ImportError as err:
-			import multiprocessing.forking as forking
-
-	class _Popen(forking.Popen):
-		def __init__(self, *args, **kw):
-			if hasattr(sys, 'frozen'):
-				# We have to set original _MEIPASS2 value from sys._MEIPASS
-				# to get --onefile mode working.
-				os.putenv('_MEIPASS2', sys._MEIPASS)
-			try:
-				super(_Popen, self).__init__(*args, **kw)
-			finally:
-				if hasattr(sys, 'frozen'):
-					# On some platforms (e.g. AIX) 'os.unsetenv()' is not
-					# available. In those cases we cannot delete the variable
-					# but only set it to the empty string. The bootloader
-					# can handle this case.
-					if hasattr(os, 'unsetenv'):
-						os.unsetenv('_MEIPASS2')
-					else:
-						os.putenv('_MEIPASS2', '')
-
-	forking.Popen = _Popen
 
 class DataSource(object):
 	bits = platform.architecture()[0]
@@ -94,7 +56,7 @@ class DataSource(object):
 
 	@staticmethod
 	def has_dmesg():
-		return len(program_paths('dmesg')) > 0
+		return len(_program_paths('dmesg')) > 0
 
 	@staticmethod
 	def has_var_run_dmesg_boot():
@@ -103,94 +65,96 @@ class DataSource(object):
 
 	@staticmethod
 	def has_cpufreq_info():
-		return len(program_paths('cpufreq-info')) > 0
+		return len(_program_paths('cpufreq-info')) > 0
 
 	@staticmethod
 	def has_sestatus():
-		return len(program_paths('sestatus')) > 0
+		return len(_program_paths('sestatus')) > 0
 
 	@staticmethod
 	def has_sysctl():
-		return len(program_paths('sysctl')) > 0
+		return len(_program_paths('sysctl')) > 0
 
 	@staticmethod
 	def has_isainfo():
-		return len(program_paths('isainfo')) > 0
+		return len(_program_paths('isainfo')) > 0
 
 	@staticmethod
 	def has_kstat():
-		return len(program_paths('kstat')) > 0
+		return len(_program_paths('kstat')) > 0
 
 	@staticmethod
 	def has_sysinfo():
-		return len(program_paths('sysinfo')) > 0
+		return len(_program_paths('sysinfo')) > 0
 
 	@staticmethod
 	def has_lscpu():
-		return len(program_paths('lscpu')) > 0
+		return len(_program_paths('lscpu')) > 0
 
 	@staticmethod
 	def has_ibm_pa_features():
-		return len(program_paths('lsprop')) > 0
+		return len(_program_paths('lsprop')) > 0
 
 	@staticmethod
 	def has_wmic():
-		returncode, output = run_and_get_stdout(['wmic', 'os', 'get', 'Version'])
+		returncode, output = _run_and_get_stdout(['wmic', 'os', 'get', 'Version'])
 		return returncode == 0 and len(output) > 0
 
 	@staticmethod
 	def cat_proc_cpuinfo():
-		return run_and_get_stdout(['cat', '/proc/cpuinfo'])
+		return _run_and_get_stdout(['cat', '/proc/cpuinfo'])
 
 	@staticmethod
 	def cpufreq_info():
-		return run_and_get_stdout(['cpufreq-info'])
+		return _run_and_get_stdout(['cpufreq-info'])
 
 	@staticmethod
 	def sestatus_allow_execheap():
-		return run_and_get_stdout(['sestatus', '-b'], ['grep', '-i', '"allow_execheap"'])[1].strip().lower().endswith('on')
+		return _run_and_get_stdout(['sestatus', '-b'], ['grep', '-i', '"allow_execheap"'])[1].strip().lower().endswith('on')
 
 	@staticmethod
 	def sestatus_allow_execmem():
-		return run_and_get_stdout(['sestatus', '-b'], ['grep', '-i', '"allow_execmem"'])[1].strip().lower().endswith('on')
+		return _run_and_get_stdout(['sestatus', '-b'], ['grep', '-i', '"allow_execmem"'])[1].strip().lower().endswith('on')
 
 	@staticmethod
 	def dmesg_a():
-		return run_and_get_stdout(['dmesg', '-a'])
+		return _run_and_get_stdout(['dmesg', '-a'])
 
 	@staticmethod
 	def cat_var_run_dmesg_boot():
-		return run_and_get_stdout(['cat', '/var/run/dmesg.boot'])
+		return _run_and_get_stdout(['cat', '/var/run/dmesg.boot'])
 
 	@staticmethod
 	def sysctl_machdep_cpu_hw_cpufrequency():
-		return run_and_get_stdout(['sysctl', 'machdep.cpu', 'hw.cpufrequency'])
+		return _run_and_get_stdout(['sysctl', 'machdep.cpu', 'hw.cpufrequency'])
 
 	@staticmethod
 	def isainfo_vb():
-		return run_and_get_stdout(['isainfo', '-vb'])
+		return _run_and_get_stdout(['isainfo', '-vb'])
 
 	@staticmethod
 	def kstat_m_cpu_info():
-		return run_and_get_stdout(['kstat', '-m', 'cpu_info'])
+		return _run_and_get_stdout(['kstat', '-m', 'cpu_info'])
 
 	@staticmethod
 	def sysinfo_cpu():
-		return run_and_get_stdout(['sysinfo', '-cpu'])
+		return _run_and_get_stdout(['sysinfo', '-cpu'])
 
 	@staticmethod
 	def lscpu():
-		return run_and_get_stdout(['lscpu'])
+		return _run_and_get_stdout(['lscpu'])
 
 	@staticmethod
 	def ibm_pa_features():
+		import glob
+
 		ibm_features = glob.glob('/proc/device-tree/cpus/*/ibm,pa-features')
 		if ibm_features:
-			return run_and_get_stdout(['lsprop', ibm_features[0]])
+			return _run_and_get_stdout(['lsprop', ibm_features[0]])
 
 	@staticmethod
 	def wmic_cpu():
-		return run_and_get_stdout(['wmic', 'cpu', 'get', 'Name,CurrentClockSpeed,L2CacheSize,L3CacheSize,Description,Caption,Manufacturer', '/format:list'])
+		return _run_and_get_stdout(['wmic', 'cpu', 'get', 'Name,CurrentClockSpeed,L2CacheSize,L3CacheSize,Description,Caption,Manufacturer', '/format:list'])
 
 	@staticmethod
 	def winreg_processor_brand():
@@ -218,7 +182,7 @@ class DataSource(object):
 		key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"Hardware\Description\System\CentralProcessor\0")
 		hz_actual = winreg.QueryValueEx(key, "~Mhz")[0]
 		winreg.CloseKey(key)
-		hz_actual = to_hz_string(hz_actual)
+		hz_actual = _to_hz_string(hz_actual)
 		return hz_actual
 
 	@staticmethod
@@ -228,14 +192,59 @@ class DataSource(object):
 		winreg.CloseKey(key)
 		return feature_bits
 
-def obj_to_b64(thing):
+
+def _program_paths(program_name):
+	paths = []
+	exts = filter(None, os.environ.get('PATHEXT', '').split(os.pathsep))
+	path = os.environ['PATH']
+	for p in os.environ['PATH'].split(os.pathsep):
+		p = os.path.join(p, program_name)
+		if os.access(p, os.X_OK):
+			paths.append(p)
+		for e in exts:
+			pext = p + e
+			if os.access(pext, os.X_OK):
+				paths.append(pext)
+	return paths
+
+def _run_and_get_stdout(command, pipe_command=None):
+	from subprocess import Popen, PIPE
+
+	if not pipe_command:
+		p1 = Popen(command, stdout=PIPE, stderr=PIPE, stdin=PIPE)
+		output = p1.communicate()[0]
+		if not IS_PY2:
+			output = output.decode(encoding='UTF-8')
+		return p1.returncode, output
+	else:
+		p1 = Popen(command, stdout=PIPE, stderr=PIPE, stdin=PIPE)
+		p2 = Popen(pipe_command, stdin=p1.stdout, stdout=PIPE, stderr=PIPE)
+		p1.stdout.close()
+		output = p2.communicate()[0]
+		if not IS_PY2:
+			output = output.decode(encoding='UTF-8')
+		return p2.returncode, output
+
+# Make sure we are running on a supported system
+def _check_arch():
+	arch, bits = _parse_arch(DataSource.raw_arch_string)
+	if not arch in ['X86_32', 'X86_64', 'ARM_7', 'ARM_8', 'PPC_64']:
+		raise Exception("py-cpuinfo currently only works on X86 and some PPC and ARM CPUs.")
+
+def _obj_to_b64(thing):
+	import pickle
+	import base64
+
 	a = thing
 	b = pickle.dumps(a)
 	c = base64.b64encode(b)
 	d = c.decode('utf8')
 	return d
 
-def b64_to_obj(thing):
+def _b64_to_obj(thing):
+	import pickle
+	import base64
+
 	try:
 		a = base64.b64decode(thing)
 		b = pickle.loads(a)
@@ -243,36 +252,34 @@ def b64_to_obj(thing):
 	except:
 		return {}
 
-def run_and_get_stdout(command, pipe_command=None):
-	if not pipe_command:
-		p1 = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
-		output = p1.communicate()[0]
-		if not PY2:
-			output = output.decode(encoding='UTF-8')
-		return p1.returncode, output
+def _utf_to_str(input):
+	if IS_PY2 and isinstance(input, unicode):
+		return input.encode('utf-8')
+	elif isinstance(input, list):
+		return [_utf_to_str(element) for element in input]
+	elif isinstance(input, dict):
+		return {_utf_to_str(key): _utf_to_str(value)
+			for key, value in input.items()}
 	else:
-		p1 = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
-		p2 = subprocess.Popen(pipe_command, stdin=p1.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-		p1.stdout.close()
-		output = p2.communicate()[0]
-		if not PY2:
-			output = output.decode(encoding='UTF-8')
-		return p2.returncode, output
+		return input
 
+def _copy_new_fields(info, new_info):
+	keys = [
+		'vendor_id', 'hardware', 'brand', 'hz_advertised', 'hz_actual',
+		'hz_advertised_raw', 'hz_actual_raw', 'arch', 'bits', 'count',
+		'raw_arch_string', 'l2_cache_size', 'l2_cache_line_size',
+		'l2_cache_associativity', 'stepping', 'model', 'family',
+		'processor_type', 'extended_model', 'extended_family', 'flags',
+		'l3_cache_size', 'l1_data_cache_size', 'l1_instruction_cache_size'
+	]
 
-def program_paths(program_name):
-	paths = []
-	exts = filter(None, os.environ.get('PATHEXT', '').split(os.pathsep))
-	path = os.environ['PATH']
-	for p in os.environ['PATH'].split(os.pathsep):
-		p = os.path.join(p, program_name)
-		if os.access(p, os.X_OK):
-			paths.append(p)
-		for e in exts:
-			pext = p + e
-			if os.access(pext, os.X_OK):
-				paths.append(pext)
-	return paths
+	for key in keys:
+		if new_info.get(key, None) and not info.get(key, None):
+			info[key] = new_info[key]
+		elif key == 'flags' and new_info.get('flags'):
+			for f in new_info['flags']:
+				if f not in info['flags']: info['flags'].append(f)
+			info['flags'].sort()
 
 def _get_field_actual(cant_be_number, raw_string, field_names):
 	for line in raw_string.splitlines():
@@ -325,13 +332,13 @@ def _get_hz_string_from_brand(processor_brand):
 		hz_brand = hz_brand.rsplit(None, 1)[1]
 
 	hz_brand = hz_brand.rstrip('mhz').rstrip('ghz').strip()
-	hz_brand = to_hz_string(hz_brand)
+	hz_brand = _to_hz_string(hz_brand)
 
 	return (scale, hz_brand)
 
-def to_friendly_hz(ticks, scale):
+def _to_friendly_hz(ticks, scale):
 	# Get the raw Hz as a string
-	left, right = to_raw_hz(ticks, scale)
+	left, right = _to_raw_hz(ticks, scale)
 	ticks = '{0}.{1}'.format(left, right)
 
 	# Get the location of the dot, and remove said dot
@@ -361,7 +368,7 @@ def to_friendly_hz(ticks, scale):
 
 	return ticks
 
-def to_raw_hz(ticks, scale):
+def _to_raw_hz(ticks, scale):
 	# Scale the numbers
 	ticks = ticks.lstrip('0')
 	old_index = ticks.index('.')
@@ -373,7 +380,7 @@ def to_raw_hz(ticks, scale):
 	left, right = int(left), int(right)
 	return (left, right)
 
-def to_hz_string(ticks):
+def _to_hz_string(ticks):
 	# Convert to string
 	ticks = '{0}'.format(ticks)
 
@@ -390,7 +397,9 @@ def to_hz_string(ticks):
 
 	return ticks
 
-def to_friendly_bytes(input):
+def _to_friendly_bytes(input):
+	import re
+
 	if not input:
 		return input
 	input = "{0}".format(input)
@@ -531,12 +540,12 @@ def _parse_dmesg_output(output):
 		}
 
 		if hz_advertised and hz_advertised != '0.0':
-			info['hz_advertised'] = to_friendly_hz(hz_advertised, scale)
-			info['hz_actual'] = to_friendly_hz(hz_actual, scale)
+			info['hz_advertised'] = _to_friendly_hz(hz_advertised, scale)
+			info['hz_actual'] = _to_friendly_hz(hz_actual, scale)
 
 		if hz_advertised and hz_advertised != '0.0':
-			info['hz_advertised_raw'] = to_raw_hz(hz_advertised, scale)
-			info['hz_actual_raw'] = to_raw_hz(hz_actual, scale)
+			info['hz_advertised_raw'] = _to_raw_hz(hz_advertised, scale)
+			info['hz_actual_raw'] = _to_raw_hz(hz_actual, scale)
 
 		return {k: v for k, v in info.items() if v}
 	except:
@@ -545,7 +554,9 @@ def _parse_dmesg_output(output):
 
 	return {}
 
-def parse_arch(raw_arch_string):
+def _parse_arch(raw_arch_string):
+	import re
+
 	arch, bits = None, None
 	raw_arch_string = raw_arch_string.lower()
 
@@ -583,7 +594,7 @@ def parse_arch(raw_arch_string):
 
 	return (arch, bits)
 
-def is_bit_set(reg, bit):
+def _is_bit_set(reg, bit):
 	mask = 1 << bit
 	is_set = reg & mask > 0
 	return is_set
@@ -809,71 +820,71 @@ class CPUID(object):
 
 		# Get the CPU flags
 		flags = {
-			'fpu' : is_bit_set(edx, 0),
-			'vme' : is_bit_set(edx, 1),
-			'de' : is_bit_set(edx, 2),
-			'pse' : is_bit_set(edx, 3),
-			'tsc' : is_bit_set(edx, 4),
-			'msr' : is_bit_set(edx, 5),
-			'pae' : is_bit_set(edx, 6),
-			'mce' : is_bit_set(edx, 7),
-			'cx8' : is_bit_set(edx, 8),
-			'apic' : is_bit_set(edx, 9),
-			#'reserved1' : is_bit_set(edx, 10),
-			'sep' : is_bit_set(edx, 11),
-			'mtrr' : is_bit_set(edx, 12),
-			'pge' : is_bit_set(edx, 13),
-			'mca' : is_bit_set(edx, 14),
-			'cmov' : is_bit_set(edx, 15),
-			'pat' : is_bit_set(edx, 16),
-			'pse36' : is_bit_set(edx, 17),
-			'pn' : is_bit_set(edx, 18),
-			'clflush' : is_bit_set(edx, 19),
-			#'reserved2' : is_bit_set(edx, 20),
-			'dts' : is_bit_set(edx, 21),
-			'acpi' : is_bit_set(edx, 22),
-			'mmx' : is_bit_set(edx, 23),
-			'fxsr' : is_bit_set(edx, 24),
-			'sse' : is_bit_set(edx, 25),
-			'sse2' : is_bit_set(edx, 26),
-			'ss' : is_bit_set(edx, 27),
-			'ht' : is_bit_set(edx, 28),
-			'tm' : is_bit_set(edx, 29),
-			'ia64' : is_bit_set(edx, 30),
-			'pbe' : is_bit_set(edx, 31),
-
-			'pni' : is_bit_set(ecx, 0),
-			'pclmulqdq' : is_bit_set(ecx, 1),
-			'dtes64' : is_bit_set(ecx, 2),
-			'monitor' : is_bit_set(ecx, 3),
-			'ds_cpl' : is_bit_set(ecx, 4),
-			'vmx' : is_bit_set(ecx, 5),
-			'smx' : is_bit_set(ecx, 6),
-			'est' : is_bit_set(ecx, 7),
-			'tm2' : is_bit_set(ecx, 8),
-			'ssse3' : is_bit_set(ecx, 9),
-			'cid' : is_bit_set(ecx, 10),
-			#'reserved3' : is_bit_set(ecx, 11),
-			'fma' : is_bit_set(ecx, 12),
-			'cx16' : is_bit_set(ecx, 13),
-			'xtpr' : is_bit_set(ecx, 14),
-			'pdcm' : is_bit_set(ecx, 15),
-			#'reserved4' : is_bit_set(ecx, 16),
-			'pcid' : is_bit_set(ecx, 17),
-			'dca' : is_bit_set(ecx, 18),
-			'sse4_1' : is_bit_set(ecx, 19),
-			'sse4_2' : is_bit_set(ecx, 20),
-			'x2apic' : is_bit_set(ecx, 21),
-			'movbe' : is_bit_set(ecx, 22),
-			'popcnt' : is_bit_set(ecx, 23),
-			'tscdeadline' : is_bit_set(ecx, 24),
-			'aes' : is_bit_set(ecx, 25),
-			'xsave' : is_bit_set(ecx, 26),
-			'osxsave' : is_bit_set(ecx, 27),
-			'avx' : is_bit_set(ecx, 28),
-			'f16c' : is_bit_set(ecx, 29),
-			'rdrnd' : is_bit_set(ecx, 30),
-			'hypervisor' : is_bit_set(ecx, 31)
+			'fpu' : _is_bit_set(edx, 0),
+			'vme' : _is_bit_set(edx, 1),
+			'de' : _is_bit_set(edx, 2),
+			'pse' : _is_bit_set(edx, 3),
+			'tsc' : _is_bit_set(edx, 4),
+			'msr' : _is_bit_set(edx, 5),
+			'pae' : _is_bit_set(edx, 6),
+			'mce' : _is_bit_set(edx, 7),
+			'cx8' : _is_bit_set(edx, 8),
+			'apic' : _is_bit_set(edx, 9),
+			#'reserved1' : _is_bit_set(edx, 10),
+			'sep' : _is_bit_set(edx, 11),
+			'mtrr' : _is_bit_set(edx, 12),
+			'pge' : _is_bit_set(edx, 13),
+			'mca' : _is_bit_set(edx, 14),
+			'cmov' : _is_bit_set(edx, 15),
+			'pat' : _is_bit_set(edx, 16),
+			'pse36' : _is_bit_set(edx, 17),
+			'pn' : _is_bit_set(edx, 18),
+			'clflush' : _is_bit_set(edx, 19),
+			#'reserved2' : _is_bit_set(edx, 20),
+			'dts' : _is_bit_set(edx, 21),
+			'acpi' : _is_bit_set(edx, 22),
+			'mmx' : _is_bit_set(edx, 23),
+			'fxsr' : _is_bit_set(edx, 24),
+			'sse' : _is_bit_set(edx, 25),
+			'sse2' : _is_bit_set(edx, 26),
+			'ss' : _is_bit_set(edx, 27),
+			'ht' : _is_bit_set(edx, 28),
+			'tm' : _is_bit_set(edx, 29),
+			'ia64' : _is_bit_set(edx, 30),
+			'pbe' : _is_bit_set(edx, 31),
+
+			'pni' : _is_bit_set(ecx, 0),
+			'pclmulqdq' : _is_bit_set(ecx, 1),
+			'dtes64' : _is_bit_set(ecx, 2),
+			'monitor' : _is_bit_set(ecx, 3),
+			'ds_cpl' : _is_bit_set(ecx, 4),
+			'vmx' : _is_bit_set(ecx, 5),
+			'smx' : _is_bit_set(ecx, 6),
+			'est' : _is_bit_set(ecx, 7),
+			'tm2' : _is_bit_set(ecx, 8),
+			'ssse3' : _is_bit_set(ecx, 9),
+			'cid' : _is_bit_set(ecx, 10),
+			#'reserved3' : _is_bit_set(ecx, 11),
+			'fma' : _is_bit_set(ecx, 12),
+			'cx16' : _is_bit_set(ecx, 13),
+			'xtpr' : _is_bit_set(ecx, 14),
+			'pdcm' : _is_bit_set(ecx, 15),
+			#'reserved4' : _is_bit_set(ecx, 16),
+			'pcid' : _is_bit_set(ecx, 17),
+			'dca' : _is_bit_set(ecx, 18),
+			'sse4_1' : _is_bit_set(ecx, 19),
+			'sse4_2' : _is_bit_set(ecx, 20),
+			'x2apic' : _is_bit_set(ecx, 21),
+			'movbe' : _is_bit_set(ecx, 22),
+			'popcnt' : _is_bit_set(ecx, 23),
+			'tscdeadline' : _is_bit_set(ecx, 24),
+			'aes' : _is_bit_set(ecx, 25),
+			'xsave' : _is_bit_set(ecx, 26),
+			'osxsave' : _is_bit_set(ecx, 27),
+			'avx' : _is_bit_set(ecx, 28),
+			'f16c' : _is_bit_set(ecx, 29),
+			'rdrnd' : _is_bit_set(ecx, 30),
+			'hypervisor' : _is_bit_set(ecx, 31)
 		}
 
 		# Get a list of only the flags that are true
@@ -901,71 +912,71 @@ class CPUID(object):
 
 			# Get the extended CPU flags
 			extended_flags = {
-				#'fsgsbase' : is_bit_set(ebx, 0),
-				#'IA32_TSC_ADJUST' : is_bit_set(ebx, 1),
-				'sgx' : is_bit_set(ebx, 2),
-				'bmi1' : is_bit_set(ebx, 3),
-				'hle' : is_bit_set(ebx, 4),
-				'avx2' : is_bit_set(ebx, 5),
-				#'reserved' : is_bit_set(ebx, 6),
-				'smep' : is_bit_set(ebx, 7),
-				'bmi2' : is_bit_set(ebx, 8),
-				'erms' : is_bit_set(ebx, 9),
-				'invpcid' : is_bit_set(ebx, 10),
-				'rtm' : is_bit_set(ebx, 11),
-				'pqm' : is_bit_set(ebx, 12),
-				#'FPU CS and FPU DS deprecated' : is_bit_set(ebx, 13),
-				'mpx' : is_bit_set(ebx, 14),
-				'pqe' : is_bit_set(ebx, 15),
-				'avx512f' : is_bit_set(ebx, 16),
-				'avx512dq' : is_bit_set(ebx, 17),
-				'rdseed' : is_bit_set(ebx, 18),
-				'adx' : is_bit_set(ebx, 19),
-				'smap' : is_bit_set(ebx, 20),
-				'avx512ifma' : is_bit_set(ebx, 21),
-				'pcommit' : is_bit_set(ebx, 22),
-				'clflushopt' : is_bit_set(ebx, 23),
-				'clwb' : is_bit_set(ebx, 24),
-				'intel_pt' : is_bit_set(ebx, 25),
-				'avx512pf' : is_bit_set(ebx, 26),
-				'avx512er' : is_bit_set(ebx, 27),
-				'avx512cd' : is_bit_set(ebx, 28),
-				'sha' : is_bit_set(ebx, 29),
-				'avx512bw' : is_bit_set(ebx, 30),
-				'avx512vl' : is_bit_set(ebx, 31),
-
-				'prefetchwt1' : is_bit_set(ecx, 0),
-				'avx512vbmi' : is_bit_set(ecx, 1),
-				'umip' : is_bit_set(ecx, 2),
-				'pku' : is_bit_set(ecx, 3),
-				'ospke' : is_bit_set(ecx, 4),
-				#'reserved' : is_bit_set(ecx, 5),
-				'avx512vbmi2' : is_bit_set(ecx, 6),
-				#'reserved' : is_bit_set(ecx, 7),
-				'gfni' : is_bit_set(ecx, 8),
-				'vaes' : is_bit_set(ecx, 9),
-				'vpclmulqdq' : is_bit_set(ecx, 10),
-				'avx512vnni' : is_bit_set(ecx, 11),
-				'avx512bitalg' : is_bit_set(ecx, 12),
-				#'reserved' : is_bit_set(ecx, 13),
-				'avx512vpopcntdq' : is_bit_set(ecx, 14),
-				#'reserved' : is_bit_set(ecx, 15),
-				#'reserved' : is_bit_set(ecx, 16),
-				#'mpx0' : is_bit_set(ecx, 17),
-				#'mpx1' : is_bit_set(ecx, 18),
-				#'mpx2' : is_bit_set(ecx, 19),
-				#'mpx3' : is_bit_set(ecx, 20),
-				#'mpx4' : is_bit_set(ecx, 21),
-				'rdpid' : is_bit_set(ecx, 22),
-				#'reserved' : is_bit_set(ecx, 23),
-				#'reserved' : is_bit_set(ecx, 24),
-				#'reserved' : is_bit_set(ecx, 25),
-				#'reserved' : is_bit_set(ecx, 26),
-				#'reserved' : is_bit_set(ecx, 27),
-				#'reserved' : is_bit_set(ecx, 28),
-				#'reserved' : is_bit_set(ecx, 29),
-				'sgx_lc' : is_bit_set(ecx, 30),
-				#'reserved' : is_bit_set(ecx, 31)
+				#'fsgsbase' : _is_bit_set(ebx, 0),
+				#'IA32_TSC_ADJUST' : _is_bit_set(ebx, 1),
+				'sgx' : _is_bit_set(ebx, 2),
+				'bmi1' : _is_bit_set(ebx, 3),
+				'hle' : _is_bit_set(ebx, 4),
+				'avx2' : _is_bit_set(ebx, 5),
+				#'reserved' : _is_bit_set(ebx, 6),
+				'smep' : _is_bit_set(ebx, 7),
+				'bmi2' : _is_bit_set(ebx, 8),
+				'erms' : _is_bit_set(ebx, 9),
+				'invpcid' : _is_bit_set(ebx, 10),
+				'rtm' : _is_bit_set(ebx, 11),
+				'pqm' : _is_bit_set(ebx, 12),
+				#'FPU CS and FPU DS deprecated' : _is_bit_set(ebx, 13),
+				'mpx' : _is_bit_set(ebx, 14),
+				'pqe' : _is_bit_set(ebx, 15),
+				'avx512f' : _is_bit_set(ebx, 16),
+				'avx512dq' : _is_bit_set(ebx, 17),
+				'rdseed' : _is_bit_set(ebx, 18),
+				'adx' : _is_bit_set(ebx, 19),
+				'smap' : _is_bit_set(ebx, 20),
+				'avx512ifma' : _is_bit_set(ebx, 21),
+				'pcommit' : _is_bit_set(ebx, 22),
+				'clflushopt' : _is_bit_set(ebx, 23),
+				'clwb' : _is_bit_set(ebx, 24),
+				'intel_pt' : _is_bit_set(ebx, 25),
+				'avx512pf' : _is_bit_set(ebx, 26),
+				'avx512er' : _is_bit_set(ebx, 27),
+				'avx512cd' : _is_bit_set(ebx, 28),
+				'sha' : _is_bit_set(ebx, 29),
+				'avx512bw' : _is_bit_set(ebx, 30),
+				'avx512vl' : _is_bit_set(ebx, 31),
+
+				'prefetchwt1' : _is_bit_set(ecx, 0),
+				'avx512vbmi' : _is_bit_set(ecx, 1),
+				'umip' : _is_bit_set(ecx, 2),
+				'pku' : _is_bit_set(ecx, 3),
+				'ospke' : _is_bit_set(ecx, 4),
+				#'reserved' : _is_bit_set(ecx, 5),
+				'avx512vbmi2' : _is_bit_set(ecx, 6),
+				#'reserved' : _is_bit_set(ecx, 7),
+				'gfni' : _is_bit_set(ecx, 8),
+				'vaes' : _is_bit_set(ecx, 9),
+				'vpclmulqdq' : _is_bit_set(ecx, 10),
+				'avx512vnni' : _is_bit_set(ecx, 11),
+				'avx512bitalg' : _is_bit_set(ecx, 12),
+				#'reserved' : _is_bit_set(ecx, 13),
+				'avx512vpopcntdq' : _is_bit_set(ecx, 14),
+				#'reserved' : _is_bit_set(ecx, 15),
+				#'reserved' : _is_bit_set(ecx, 16),
+				#'mpx0' : _is_bit_set(ecx, 17),
+				#'mpx1' : _is_bit_set(ecx, 18),
+				#'mpx2' : _is_bit_set(ecx, 19),
+				#'mpx3' : _is_bit_set(ecx, 20),
+				#'mpx4' : _is_bit_set(ecx, 21),
+				'rdpid' : _is_bit_set(ecx, 22),
+				#'reserved' : _is_bit_set(ecx, 23),
+				#'reserved' : _is_bit_set(ecx, 24),
+				#'reserved' : _is_bit_set(ecx, 25),
+				#'reserved' : _is_bit_set(ecx, 26),
+				#'reserved' : _is_bit_set(ecx, 27),
+				#'reserved' : _is_bit_set(ecx, 28),
+				#'reserved' : _is_bit_set(ecx, 29),
+				'sgx_lc' : _is_bit_set(ecx, 30),
+				#'reserved' : _is_bit_set(ecx, 31)
 			}
 
 			# Get a list of only the flags that are true
@@ -992,71 +1003,71 @@ class CPUID(object):
 
 			# Get the extended CPU flags
 			extended_flags = {
-				'fpu' : is_bit_set(ebx, 0),
-				'vme' : is_bit_set(ebx, 1),
-				'de' : is_bit_set(ebx, 2),
-				'pse' : is_bit_set(ebx, 3),
-				'tsc' : is_bit_set(ebx, 4),
-				'msr' : is_bit_set(ebx, 5),
-				'pae' : is_bit_set(ebx, 6),
-				'mce' : is_bit_set(ebx, 7),
-				'cx8' : is_bit_set(ebx, 8),
-				'apic' : is_bit_set(ebx, 9),
-				#'reserved' : is_bit_set(ebx, 10),
-				'syscall' : is_bit_set(ebx, 11),
-				'mtrr' : is_bit_set(ebx, 12),
-				'pge' : is_bit_set(ebx, 13),
-				'mca' : is_bit_set(ebx, 14),
-				'cmov' : is_bit_set(ebx, 15),
-				'pat' : is_bit_set(ebx, 16),
-				'pse36' : is_bit_set(ebx, 17),
-				#'reserved' : is_bit_set(ebx, 18),
-				'mp' : is_bit_set(ebx, 19),
-				'nx' : is_bit_set(ebx, 20),
-				#'reserved' : is_bit_set(ebx, 21),
-				'mmxext' : is_bit_set(ebx, 22),
-				'mmx' : is_bit_set(ebx, 23),
-				'fxsr' : is_bit_set(ebx, 24),
-				'fxsr_opt' : is_bit_set(ebx, 25),
-				'pdpe1gp' : is_bit_set(ebx, 26),
-				'rdtscp' : is_bit_set(ebx, 27),
-				#'reserved' : is_bit_set(ebx, 28),
-				'lm' : is_bit_set(ebx, 29),
-				'3dnowext' : is_bit_set(ebx, 30),
-				'3dnow' : is_bit_set(ebx, 31),
-
-				'lahf_lm' : is_bit_set(ecx, 0),
-				'cmp_legacy' : is_bit_set(ecx, 1),
-				'svm' : is_bit_set(ecx, 2),
-				'extapic' : is_bit_set(ecx, 3),
-				'cr8_legacy' : is_bit_set(ecx, 4),
-				'abm' : is_bit_set(ecx, 5),
-				'sse4a' : is_bit_set(ecx, 6),
-				'misalignsse' : is_bit_set(ecx, 7),
-				'3dnowprefetch' : is_bit_set(ecx, 8),
-				'osvw' : is_bit_set(ecx, 9),
-				'ibs' : is_bit_set(ecx, 10),
-				'xop' : is_bit_set(ecx, 11),
-				'skinit' : is_bit_set(ecx, 12),
-				'wdt' : is_bit_set(ecx, 13),
-				#'reserved' : is_bit_set(ecx, 14),
-				'lwp' : is_bit_set(ecx, 15),
-				'fma4' : is_bit_set(ecx, 16),
-				'tce' : is_bit_set(ecx, 17),
-				#'reserved' : is_bit_set(ecx, 18),
-				'nodeid_msr' : is_bit_set(ecx, 19),
-				#'reserved' : is_bit_set(ecx, 20),
-				'tbm' : is_bit_set(ecx, 21),
-				'topoext' : is_bit_set(ecx, 22),
-				'perfctr_core' : is_bit_set(ecx, 23),
-				'perfctr_nb' : is_bit_set(ecx, 24),
-				#'reserved' : is_bit_set(ecx, 25),
-				'dbx' : is_bit_set(ecx, 26),
-				'perftsc' : is_bit_set(ecx, 27),
-				'pci_l2i' : is_bit_set(ecx, 28),
-				#'reserved' : is_bit_set(ecx, 29),
-				#'reserved' : is_bit_set(ecx, 30),
-				#'reserved' : is_bit_set(ecx, 31)
+				'fpu' : _is_bit_set(ebx, 0),
+				'vme' : _is_bit_set(ebx, 1),
+				'de' : _is_bit_set(ebx, 2),
+				'pse' : _is_bit_set(ebx, 3),
+				'tsc' : _is_bit_set(ebx, 4),
+				'msr' : _is_bit_set(ebx, 5),
+				'pae' : _is_bit_set(ebx, 6),
+				'mce' : _is_bit_set(ebx, 7),
+				'cx8' : _is_bit_set(ebx, 8),
+				'apic' : _is_bit_set(ebx, 9),
+				#'reserved' : _is_bit_set(ebx, 10),
+				'syscall' : _is_bit_set(ebx, 11),
+				'mtrr' : _is_bit_set(ebx, 12),
+				'pge' : _is_bit_set(ebx, 13),
+				'mca' : _is_bit_set(ebx, 14),
+				'cmov' : _is_bit_set(ebx, 15),
+				'pat' : _is_bit_set(ebx, 16),
+				'pse36' : _is_bit_set(ebx, 17),
+				#'reserved' : _is_bit_set(ebx, 18),
+				'mp' : _is_bit_set(ebx, 19),
+				'nx' : _is_bit_set(ebx, 20),
+				#'reserved' : _is_bit_set(ebx, 21),
+				'mmxext' : _is_bit_set(ebx, 22),
+				'mmx' : _is_bit_set(ebx, 23),
+				'fxsr' : _is_bit_set(ebx, 24),
+				'fxsr_opt' : _is_bit_set(ebx, 25),
+				'pdpe1gp' : _is_bit_set(ebx, 26),
+				'rdtscp' : _is_bit_set(ebx, 27),
+				#'reserved' : _is_bit_set(ebx, 28),
+				'lm' : _is_bit_set(ebx, 29),
+				'3dnowext' : _is_bit_set(ebx, 30),
+				'3dnow' : _is_bit_set(ebx, 31),
+
+				'lahf_lm' : _is_bit_set(ecx, 0),
+				'cmp_legacy' : _is_bit_set(ecx, 1),
+				'svm' : _is_bit_set(ecx, 2),
+				'extapic' : _is_bit_set(ecx, 3),
+				'cr8_legacy' : _is_bit_set(ecx, 4),
+				'abm' : _is_bit_set(ecx, 5),
+				'sse4a' : _is_bit_set(ecx, 6),
+				'misalignsse' : _is_bit_set(ecx, 7),
+				'3dnowprefetch' : _is_bit_set(ecx, 8),
+				'osvw' : _is_bit_set(ecx, 9),
+				'ibs' : _is_bit_set(ecx, 10),
+				'xop' : _is_bit_set(ecx, 11),
+				'skinit' : _is_bit_set(ecx, 12),
+				'wdt' : _is_bit_set(ecx, 13),
+				#'reserved' : _is_bit_set(ecx, 14),
+				'lwp' : _is_bit_set(ecx, 15),
+				'fma4' : _is_bit_set(ecx, 16),
+				'tce' : _is_bit_set(ecx, 17),
+				#'reserved' : _is_bit_set(ecx, 18),
+				'nodeid_msr' : _is_bit_set(ecx, 19),
+				#'reserved' : _is_bit_set(ecx, 20),
+				'tbm' : _is_bit_set(ecx, 21),
+				'topoext' : _is_bit_set(ecx, 22),
+				'perfctr_core' : _is_bit_set(ecx, 23),
+				'perfctr_nb' : _is_bit_set(ecx, 24),
+				#'reserved' : _is_bit_set(ecx, 25),
+				'dbx' : _is_bit_set(ecx, 26),
+				'perftsc' : _is_bit_set(ecx, 27),
+				'pci_l2i' : _is_bit_set(ecx, 28),
+				#'reserved' : _is_bit_set(ecx, 29),
+				#'reserved' : _is_bit_set(ecx, 30),
+				#'reserved' : _is_bit_set(ecx, 31)
 			}
 
 			# Get a list of only the flags that are true
@@ -1194,6 +1205,8 @@ class CPUID(object):
 		return retval
 
 	def get_raw_hz(self):
+		import time
+
 		start = self.get_ticks()
 
 		time.sleep(1)
@@ -1216,17 +1229,17 @@ def _actual_get_cpu_info_from_cpuid(queue):
 	sys.stderr = open(os.devnull, 'w')
 
 	# Get the CPU arch and bits
-	arch, bits = parse_arch(DataSource.raw_arch_string)
+	arch, bits = _parse_arch(DataSource.raw_arch_string)
 
 	# Return none if this is not an X86 CPU
 	if not arch in ['X86_32', 'X86_64']:
-		queue.put(obj_to_b64({}))
+		queue.put(_obj_to_b64({}))
 		return
 
 	# Return none if SE Linux is in enforcing mode
 	cpuid = CPUID()
 	if cpuid.is_selinux_enforcing:
-		queue.put(obj_to_b64({}))
+		queue.put(_obj_to_b64({}))
 		return
 
 	# Get the cpu info from the CPUID register
@@ -1238,7 +1251,7 @@ def _actual_get_cpu_info_from_cpuid(queue):
 
 	# Get the Hz and scale
 	hz_actual = cpuid.get_raw_hz()
-	hz_actual = to_hz_string(hz_actual)
+	hz_actual = _to_hz_string(hz_actual)
 
 	# Get the Hz and scale
 	scale, hz_advertised = _get_hz_string_from_brand(processor_brand)
@@ -1247,12 +1260,12 @@ def _actual_get_cpu_info_from_cpuid(queue):
 	'hardware' : '',
 	'brand' : processor_brand,
 
-	'hz_advertised' : to_friendly_hz(hz_advertised, scale),
-	'hz_actual' : to_friendly_hz(hz_actual, 0),
-	'hz_advertised_raw' : to_raw_hz(hz_advertised, scale),
-	'hz_actual_raw' : to_raw_hz(hz_actual, 0),
+	'hz_advertised' : _to_friendly_hz(hz_advertised, scale),
+	'hz_actual' : _to_friendly_hz(hz_actual, 0),
+	'hz_advertised_raw' : _to_raw_hz(hz_advertised, scale),
+	'hz_actual_raw' : _to_raw_hz(hz_actual, 0),
 
-	'l2_cache_size' : to_friendly_bytes(cache_info['size_kb']),
+	'l2_cache_size' : _to_friendly_bytes(cache_info['size_kb']),
 	'l2_cache_line_size' : cache_info['line_size_b'],
 	'l2_cache_associativity' : hex(cache_info['associativity']),
 
@@ -1266,7 +1279,7 @@ def _actual_get_cpu_info_from_cpuid(queue):
 	}
 
 	info = {k: v for k, v in info.items() if v}
-	queue.put(obj_to_b64(info))
+	queue.put(_obj_to_b64(info))
 
 def _get_cpu_info_from_cpuid():
 	'''
@@ -1281,7 +1294,7 @@ def _get_cpu_info_from_cpuid():
 		return {}
 
 	# Get the CPU arch and bits
-	arch, bits = parse_arch(DataSource.raw_arch_string)
+	arch, bits = _parse_arch(DataSource.raw_arch_string)
 
 	# Return {} if this is not an X86 CPU
 	if not arch in ['X86_32', 'X86_64']:
@@ -1304,7 +1317,7 @@ def _get_cpu_info_from_cpuid():
 		# Return the result, only if there is something to read
 		if not queue.empty():
 			output = queue.get()
-			return b64_to_obj(output)
+			return _b64_to_obj(output)
 	except:
 		pass
 
@@ -1342,7 +1355,7 @@ def _get_cpu_info_from_proc_cpuinfo():
 		# Convert from MHz string to Hz
 		hz_actual = _get_field(False, output, None, '', 'cpu MHz', 'cpu speed', 'clock')
 		hz_actual = hz_actual.lower().rstrip('mhz').strip()
-		hz_actual = to_hz_string(hz_actual)
+		hz_actual = _to_hz_string(hz_actual)
 
 		# Convert from GHz/MHz string to Hz
 		scale, hz_advertised = (0, None)
@@ -1355,7 +1368,7 @@ def _get_cpu_info_from_proc_cpuinfo():
 		'hardware' : hardware,
 		'brand' : processor_brand,
 
-		'l3_cache_size' : to_friendly_bytes(cache_size),
+		'l3_cache_size' : _to_friendly_bytes(cache_size),
 		'flags' : flags,
 		'vendor_id' : vendor_id,
 		'stepping' : stepping,
@@ -1371,12 +1384,12 @@ def _get_cpu_info_from_proc_cpuinfo():
 			hz_actual = hz_advertised
 
 		# Add the Hz if there is one
-		if to_raw_hz(hz_advertised, scale) > (0, 0):
-			info['hz_advertised'] = to_friendly_hz(hz_advertised, scale)
-			info['hz_advertised_raw'] = to_raw_hz(hz_advertised, scale)
-		if to_raw_hz(hz_actual, scale) > (0, 0):
-			info['hz_actual'] = to_friendly_hz(hz_actual, 6)
-			info['hz_actual_raw'] = to_raw_hz(hz_actual, 6)
+		if _to_raw_hz(hz_advertised, scale) > (0, 0):
+			info['hz_advertised'] = _to_friendly_hz(hz_advertised, scale)
+			info['hz_advertised_raw'] = _to_raw_hz(hz_advertised, scale)
+		if _to_raw_hz(hz_actual, scale) > (0, 0):
+			info['hz_actual'] = _to_friendly_hz(hz_actual, 6)
+			info['hz_actual_raw'] = _to_raw_hz(hz_actual, 6)
 
 		info = {k: v for k, v in info.items() if v}
 		return info
@@ -1409,13 +1422,13 @@ def _get_cpu_info_from_cpufreq_info():
 		elif hz_brand.endswith('ghz'):
 			scale = 9
 		hz_brand = hz_brand.rstrip('mhz').rstrip('ghz').strip()
-		hz_brand = to_hz_string(hz_brand)
+		hz_brand = _to_hz_string(hz_brand)
 
 		info = {
-			'hz_advertised' : to_friendly_hz(hz_brand, scale),
-			'hz_actual' : to_friendly_hz(hz_brand, scale),
-			'hz_advertised_raw' : to_raw_hz(hz_brand, scale),
-			'hz_actual_raw' : to_raw_hz(hz_brand, scale),
+			'hz_advertised' : _to_friendly_hz(hz_brand, scale),
+			'hz_actual' : _to_friendly_hz(hz_brand, scale),
+			'hz_advertised_raw' : _to_raw_hz(hz_brand, scale),
+			'hz_actual_raw' : _to_raw_hz(hz_brand, scale),
 		}
 
 		info = {k: v for k, v in info.items() if v}
@@ -1441,12 +1454,12 @@ def _get_cpu_info_from_lscpu():
 
 		new_hz = _get_field(False, output, None, None, 'CPU max MHz', 'CPU MHz')
 		if new_hz:
-			new_hz = to_hz_string(new_hz)
+			new_hz = _to_hz_string(new_hz)
 			scale = 6
-			info['hz_advertised'] = to_friendly_hz(new_hz, scale)
-			info['hz_actual'] = to_friendly_hz(new_hz, scale)
-			info['hz_advertised_raw'] = to_raw_hz(new_hz, scale)
-			info['hz_actual_raw'] = to_raw_hz(new_hz, scale)
+			info['hz_advertised'] = _to_friendly_hz(new_hz, scale)
+			info['hz_actual'] = _to_friendly_hz(new_hz, scale)
+			info['hz_advertised_raw'] = _to_raw_hz(new_hz, scale)
+			info['hz_actual_raw'] = _to_raw_hz(new_hz, scale)
 
 		vendor_id = _get_field(False, output, None, None, 'Vendor ID')
 		if vendor_id:
@@ -1470,19 +1483,19 @@ def _get_cpu_info_from_lscpu():
 
 		l1_data_cache_size = _get_field(False, output, None, None, 'L1d cache')
 		if l1_data_cache_size:
-			info['l1_data_cache_size'] = to_friendly_bytes(l1_data_cache_size)
+			info['l1_data_cache_size'] = _to_friendly_bytes(l1_data_cache_size)
 
 		l1_instruction_cache_size = _get_field(False, output, None, None, 'L1i cache')
 		if l1_instruction_cache_size:
-			info['l1_instruction_cache_size'] = to_friendly_bytes(l1_instruction_cache_size)
+			info['l1_instruction_cache_size'] = _to_friendly_bytes(l1_instruction_cache_size)
 
 		l2_cache_size = _get_field(False, output, None, None, 'L2 cache')
 		if l2_cache_size:
-			info['l2_cache_size'] = to_friendly_bytes(l2_cache_size)
+			info['l2_cache_size'] = _to_friendly_bytes(l2_cache_size)
 
 		l3_cache_size = _get_field(False, output, None, None, 'L3 cache')
 		if l3_cache_size:
-			info['l3_cache_size'] = to_friendly_bytes(l3_cache_size)
+			info['l3_cache_size'] = _to_friendly_bytes(l3_cache_size)
 
 		# Flags
 		flags = _get_field(False, output, None, None, 'flags', 'Features')
@@ -1543,84 +1556,84 @@ def _get_cpu_info_from_ibm_pa_features():
 		# Get the CPU flags
 		flags = {
 			# Byte 0
-			'mmu' : is_bit_set(left, 0),
-			'fpu' : is_bit_set(left, 1),
-			'slb' : is_bit_set(left, 2),
-			'run' : is_bit_set(left, 3),
-			#'reserved' : is_bit_set(left, 4),
-			'dabr' : is_bit_set(left, 5),
-			'ne' : is_bit_set(left, 6),
-			'wtr' : is_bit_set(left, 7),
+			'mmu' : _is_bit_set(left, 0),
+			'fpu' : _is_bit_set(left, 1),
+			'slb' : _is_bit_set(left, 2),
+			'run' : _is_bit_set(left, 3),
+			#'reserved' : _is_bit_set(left, 4),
+			'dabr' : _is_bit_set(left, 5),
+			'ne' : _is_bit_set(left, 6),
+			'wtr' : _is_bit_set(left, 7),
 
 			# Byte 1
-			'mcr' : is_bit_set(left, 8),
-			'dsisr' : is_bit_set(left, 9),
-			'lp' : is_bit_set(left, 10),
-			'ri' : is_bit_set(left, 11),
-			'dabrx' : is_bit_set(left, 12),
-			'sprg3' : is_bit_set(left, 13),
-			'rislb' : is_bit_set(left, 14),
-			'pp' : is_bit_set(left, 15),
+			'mcr' : _is_bit_set(left, 8),
+			'dsisr' : _is_bit_set(left, 9),
+			'lp' : _is_bit_set(left, 10),
+			'ri' : _is_bit_set(left, 11),
+			'dabrx' : _is_bit_set(left, 12),
+			'sprg3' : _is_bit_set(left, 13),
+			'rislb' : _is_bit_set(left, 14),
+			'pp' : _is_bit_set(left, 15),
 
 			# Byte 2
-			'vpm' : is_bit_set(left, 16),
-			'dss_2.05' : is_bit_set(left, 17),
-			#'reserved' : is_bit_set(left, 18),
-			'dar' : is_bit_set(left, 19),
-			#'reserved' : is_bit_set(left, 20),
-			'ppr' : is_bit_set(left, 21),
-			'dss_2.02' : is_bit_set(left, 22),
-			'dss_2.06' : is_bit_set(left, 23),
+			'vpm' : _is_bit_set(left, 16),
+			'dss_2.05' : _is_bit_set(left, 17),
+			#'reserved' : _is_bit_set(left, 18),
+			'dar' : _is_bit_set(left, 19),
+			#'reserved' : _is_bit_set(left, 20),
+			'ppr' : _is_bit_set(left, 21),
+			'dss_2.02' : _is_bit_set(left, 22),
+			'dss_2.06' : _is_bit_set(left, 23),
 
 			# Byte 3
-			'lsd_in_dscr' : is_bit_set(left, 24),
-			'ugr_in_dscr' : is_bit_set(left, 25),
-			#'reserved' : is_bit_set(left, 26),
-			#'reserved' : is_bit_set(left, 27),
-			#'reserved' : is_bit_set(left, 28),
-			#'reserved' : is_bit_set(left, 29),
-			#'reserved' : is_bit_set(left, 30),
-			#'reserved' : is_bit_set(left, 31),
+			'lsd_in_dscr' : _is_bit_set(left, 24),
+			'ugr_in_dscr' : _is_bit_set(left, 25),
+			#'reserved' : _is_bit_set(left, 26),
+			#'reserved' : _is_bit_set(left, 27),
+			#'reserved' : _is_bit_set(left, 28),
+			#'reserved' : _is_bit_set(left, 29),
+			#'reserved' : _is_bit_set(left, 30),
+			#'reserved' : _is_bit_set(left, 31),
 
 			# Byte 4
-			'sso_2.06' : is_bit_set(right, 0),
-			#'reserved' : is_bit_set(right, 1),
-			#'reserved' : is_bit_set(right, 2),
-			#'reserved' : is_bit_set(right, 3),
-			#'reserved' : is_bit_set(right, 4),
-			#'reserved' : is_bit_set(right, 5),
-			#'reserved' : is_bit_set(right, 6),
-			#'reserved' : is_bit_set(right, 7),
+			'sso_2.06' : _is_bit_set(right, 0),
+			#'reserved' : _is_bit_set(right, 1),
+			#'reserved' : _is_bit_set(right, 2),
+			#'reserved' : _is_bit_set(right, 3),
+			#'reserved' : _is_bit_set(right, 4),
+			#'reserved' : _is_bit_set(right, 5),
+			#'reserved' : _is_bit_set(right, 6),
+			#'reserved' : _is_bit_set(right, 7),
 
 			# Byte 5
-			'le' : is_bit_set(right, 8),
-			'cfar' : is_bit_set(right, 9),
-			'eb' : is_bit_set(right, 10),
-			'lsq_2.07' : is_bit_set(right, 11),
-			#'reserved' : is_bit_set(right, 12),
-			#'reserved' : is_bit_set(right, 13),
-			#'reserved' : is_bit_set(right, 14),
-			#'reserved' : is_bit_set(right, 15),
+			'le' : _is_bit_set(right, 8),
+			'cfar' : _is_bit_set(right, 9),
+			'eb' : _is_bit_set(right, 10),
+			'lsq_2.07' : _is_bit_set(right, 11),
+			#'reserved' : _is_bit_set(right, 12),
+			#'reserved' : _is_bit_set(right, 13),
+			#'reserved' : _is_bit_set(right, 14),
+			#'reserved' : _is_bit_set(right, 15),
 
 			# Byte 6
-			'dss_2.07' : is_bit_set(right, 16),
-			#'reserved' : is_bit_set(right, 17),
-			#'reserved' : is_bit_set(right, 18),
-			#'reserved' : is_bit_set(right, 19),
-			#'reserved' : is_bit_set(right, 20),
-			#'reserved' : is_bit_set(right, 21),
-			#'reserved' : is_bit_set(right, 22),
-			#'reserved' : is_bit_set(right, 23),
+			'dss_2.07' : _is_bit_set(right, 16),
+			#'reserved' : _is_bit_set(right, 17),
+			#'reserved' : _is_bit_set(right, 18),
+			#'reserved' : _is_bit_set(right, 19),
+			#'reserved' : _is_bit_set(right, 20),
+			#'reserved' : _is_bit_set(right, 21),
+			#'reserved' : _is_bit_set(right, 22),
+			#'reserved' : _is_bit_set(right, 23),
 
 			# Byte 7
-			#'reserved' : is_bit_set(right, 24),
-			#'reserved' : is_bit_set(right, 25),
-			#'reserved' : is_bit_set(right, 26),
-			#'reserved' : is_bit_set(right, 27),
-			#'reserved' : is_bit_set(right, 28),
-			#'reserved' : is_bit_set(right, 29),
-			#'reserved' : is_bit_set(right, 30),
-			#'reserved' : is_bit_set(right, 31),
+			#'reserved' : _is_bit_set(right, 24),
+			#'reserved' : _is_bit_set(right, 25),
+			#'reserved' : _is_bit_set(right, 26),
+			#'reserved' : _is_bit_set(right, 27),
+			#'reserved' : _is_bit_set(right, 28),
+			#'reserved' : _is_bit_set(right, 29),
+			#'reserved' : _is_bit_set(right, 30),
+			#'reserved' : _is_bit_set(right, 31),
 		}
 
 		# Get a list of only the flags that are true
@@ -1686,18 +1699,18 @@ def _get_cpu_info_from_sysctl():
 		# Convert from GHz/MHz string to Hz
 		scale, hz_advertised = _get_hz_string_from_brand(processor_brand)
 		hz_actual = _get_field(False, output, None, None, 'hw.cpufrequency')
-		hz_actual = to_hz_string(hz_actual)
+		hz_actual = _to_hz_string(hz_actual)
 
 		info = {
 		'vendor_id' : vendor_id,
 		'brand' : processor_brand,
 
-		'hz_advertised' : to_friendly_hz(hz_advertised, scale),
-		'hz_actual' : to_friendly_hz(hz_actual, 0),
-		'hz_advertised_raw' : to_raw_hz(hz_advertised, scale),
-		'hz_actual_raw' : to_raw_hz(hz_actual, 0),
+		'hz_advertised' : _to_friendly_hz(hz_advertised, scale),
+		'hz_actual' : _to_friendly_hz(hz_actual, 0),
+		'hz_advertised_raw' : _to_raw_hz(hz_advertised, scale),
+		'hz_actual_raw' : _to_raw_hz(hz_actual, 0),
 
-		'l2_cache_size' : to_friendly_bytes(cache_size),
+		'l2_cache_size' : _to_friendly_bytes(cache_size),
 
 		'stepping' : stepping,
 		'model' : model,
@@ -1759,12 +1772,12 @@ def _get_cpu_info_from_sysinfo_v1():
 		'vendor_id' : vendor_id,
 		'brand' : processor_brand,
 
-		'hz_advertised' : to_friendly_hz(hz_advertised, scale),
-		'hz_actual' : to_friendly_hz(hz_actual, scale),
-		'hz_advertised_raw' : to_raw_hz(hz_advertised, scale),
-		'hz_actual_raw' : to_raw_hz(hz_actual, scale),
+		'hz_advertised' : _to_friendly_hz(hz_advertised, scale),
+		'hz_actual' : _to_friendly_hz(hz_actual, scale),
+		'hz_advertised_raw' : _to_raw_hz(hz_advertised, scale),
+		'hz_actual_raw' : _to_raw_hz(hz_actual, scale),
 
-		'l2_cache_size' : to_friendly_bytes(cache_size),
+		'l2_cache_size' : _to_friendly_bytes(cache_size),
 
 		'stepping' : stepping,
 		'model' : model,
@@ -1824,12 +1837,12 @@ def _get_cpu_info_from_sysinfo_v2():
 		'vendor_id' : vendor_id,
 		'brand' : processor_brand,
 
-		'hz_advertised' : to_friendly_hz(hz_advertised, scale),
-		'hz_actual' : to_friendly_hz(hz_actual, scale),
-		'hz_advertised_raw' : to_raw_hz(hz_advertised, scale),
-		'hz_actual_raw' : to_raw_hz(hz_actual, scale),
+		'hz_advertised' : _to_friendly_hz(hz_advertised, scale),
+		'hz_actual' : _to_friendly_hz(hz_actual, scale),
+		'hz_advertised_raw' : _to_raw_hz(hz_advertised, scale),
+		'hz_actual_raw' : _to_raw_hz(hz_actual, scale),
 
-		'l2_cache_size' : to_friendly_bytes(cache_size),
+		'l2_cache_size' : _to_friendly_bytes(cache_size),
 
 		'stepping' : stepping,
 		'model' : model,
@@ -1870,7 +1883,7 @@ def _get_cpu_info_from_wmic():
 		hz_actual = value.get('CurrentClockSpeed')
 		scale_actual = 6
 		if hz_actual:
-			hz_actual = to_hz_string(hz_actual)
+			hz_actual = _to_hz_string(hz_actual)
 
 		# Get cache sizes
 		l2_cache_size = value.get('L2CacheSize')
@@ -1902,10 +1915,10 @@ def _get_cpu_info_from_wmic():
 			'vendor_id' : value.get('Manufacturer'),
 			'brand' : processor_brand,
 
-			'hz_advertised' : to_friendly_hz(hz_advertised, scale_advertised),
-			'hz_actual' : to_friendly_hz(hz_actual, scale_actual),
-			'hz_advertised_raw' : to_raw_hz(hz_advertised, scale_advertised),
-			'hz_actual_raw' : to_raw_hz(hz_actual, scale_actual),
+			'hz_advertised' : _to_friendly_hz(hz_advertised, scale_advertised),
+			'hz_actual' : _to_friendly_hz(hz_actual, scale_actual),
+			'hz_advertised_raw' : _to_raw_hz(hz_advertised, scale_advertised),
+			'hz_actual_raw' : _to_raw_hz(hz_actual, scale_actual),
 
 			'l2_cache_size' : l2_cache_size,
 			'l3_cache_size' : l3_cache_size,
@@ -1940,11 +1953,11 @@ def _get_cpu_info_from_registry():
 
 		# Get the CPU arch and bits
 		raw_arch_string = DataSource.winreg_raw_arch_string()
-		arch, bits = parse_arch(raw_arch_string)
+		arch, bits = _parse_arch(raw_arch_string)
 
 		# Get the actual CPU Hz
 		hz_actual = DataSource.winreg_hz_actual()
-		hz_actual = to_hz_string(hz_actual)
+		hz_actual = _to_hz_string(hz_actual)
 
 		# Get the advertised CPU Hz
 		scale, hz_advertised = _get_hz_string_from_brand(processor_brand)
@@ -2003,10 +2016,10 @@ def _get_cpu_info_from_registry():
 		'vendor_id' : vendor_id,
 		'brand' : processor_brand,
 
-		'hz_advertised' : to_friendly_hz(hz_advertised, scale),
-		'hz_actual' : to_friendly_hz(hz_actual, 6),
-		'hz_advertised_raw' : to_raw_hz(hz_advertised, scale),
-		'hz_actual_raw' : to_raw_hz(hz_actual, 6),
+		'hz_advertised' : _to_friendly_hz(hz_advertised, scale),
+		'hz_actual' : _to_friendly_hz(hz_actual, 6),
+		'hz_advertised_raw' : _to_raw_hz(hz_advertised, scale),
+		'hz_actual_raw' : _to_raw_hz(hz_actual, 6),
 
 		'flags' : flags
 		}
@@ -2050,20 +2063,20 @@ def _get_cpu_info_from_kstat():
 		# Convert from GHz/MHz string to Hz
 		scale = 6
 		hz_advertised = kstat.split('\tclock_MHz ')[1].split('\n')[0].strip()
-		hz_advertised = to_hz_string(hz_advertised)
+		hz_advertised = _to_hz_string(hz_advertised)
 
 		# Convert from GHz/MHz string to Hz
 		hz_actual = kstat.split('\tcurrent_clock_Hz ')[1].split('\n')[0].strip()
-		hz_actual = to_hz_string(hz_actual)
+		hz_actual = _to_hz_string(hz_actual)
 
 		info = {
 		'vendor_id' : vendor_id,
 		'brand' : processor_brand,
 
-		'hz_advertised' : to_friendly_hz(hz_advertised, scale),
-		'hz_actual' : to_friendly_hz(hz_actual, 0),
-		'hz_advertised_raw' : to_raw_hz(hz_advertised, scale),
-		'hz_actual_raw' : to_raw_hz(hz_actual, 0),
+		'hz_advertised' : _to_friendly_hz(hz_advertised, scale),
+		'hz_actual' : _to_friendly_hz(hz_actual, 0),
+		'hz_advertised_raw' : _to_raw_hz(hz_advertised, scale),
+		'hz_actual_raw' : _to_raw_hz(hz_actual, 0),
 
 		'stepping' : stepping,
 		'model' : model,
@@ -2076,32 +2089,14 @@ def _get_cpu_info_from_kstat():
 	except:
 		return {}
 
-def CopyNewFields(info, new_info):
-	keys = [
-		'vendor_id', 'hardware', 'brand', 'hz_advertised', 'hz_actual',
-		'hz_advertised_raw', 'hz_actual_raw', 'arch', 'bits', 'count',
-		'raw_arch_string', 'l2_cache_size', 'l2_cache_line_size',
-		'l2_cache_associativity', 'stepping', 'model', 'family',
-		'processor_type', 'extended_model', 'extended_family', 'flags',
-		'l3_cache_size', 'l1_data_cache_size', 'l1_instruction_cache_size'
-	]
-
-	for key in keys:
-		if new_info.get(key, None) and not info.get(key, None):
-			info[key] = new_info[key]
-		elif key == 'flags' and new_info.get('flags'):
-			for f in new_info['flags']:
-				if f not in info['flags']: info['flags'].append(f)
-			info['flags'].sort()
-
-def get_cpu_info():
+def _get_cpu_info_internal():
 	'''
 	Returns the CPU info by using the best sources of information for your OS.
 	Returns {} if nothing is found.
 	'''
 
 	# Get the CPU arch and bits
-	arch, bits = parse_arch(DataSource.raw_arch_string)
+	arch, bits = _parse_arch(DataSource.raw_arch_string)
 
 	friendly_maxsize = { 2**31-1: '32 bit', 2**63-1: '64 bit' }.get(sys.maxsize) or 'unknown bits'
 	friendly_version = "{0}.{1}.{2}.{3}.{4}".format(*sys.version_info)
@@ -2117,60 +2112,117 @@ def get_cpu_info():
 	}
 
 	# Try the Windows wmic
-	CopyNewFields(info, _get_cpu_info_from_wmic())
+	_copy_new_fields(info, _get_cpu_info_from_wmic())
 
 	# Try the Windows registry
-	CopyNewFields(info, _get_cpu_info_from_registry())
+	_copy_new_fields(info, _get_cpu_info_from_registry())
 
 	# Try /proc/cpuinfo
-	CopyNewFields(info, _get_cpu_info_from_proc_cpuinfo())
+	_copy_new_fields(info, _get_cpu_info_from_proc_cpuinfo())
 
 	# Try cpufreq-info
-	CopyNewFields(info, _get_cpu_info_from_cpufreq_info())
+	_copy_new_fields(info, _get_cpu_info_from_cpufreq_info())
 
 	# Try LSCPU
-	CopyNewFields(info, _get_cpu_info_from_lscpu())
+	_copy_new_fields(info, _get_cpu_info_from_lscpu())
 
 	# Try sysctl
-	CopyNewFields(info, _get_cpu_info_from_sysctl())
+	_copy_new_fields(info, _get_cpu_info_from_sysctl())
 
 	# Try kstat
-	CopyNewFields(info, _get_cpu_info_from_kstat())
+	_copy_new_fields(info, _get_cpu_info_from_kstat())
 
 	# Try dmesg
-	CopyNewFields(info, _get_cpu_info_from_dmesg())
+	_copy_new_fields(info, _get_cpu_info_from_dmesg())
 
 	# Try /var/run/dmesg.boot
-	CopyNewFields(info, _get_cpu_info_from_cat_var_run_dmesg_boot())
+	_copy_new_fields(info, _get_cpu_info_from_cat_var_run_dmesg_boot())
 
 	# Try lsprop ibm,pa-features
-	CopyNewFields(info, _get_cpu_info_from_ibm_pa_features())
+	_copy_new_fields(info, _get_cpu_info_from_ibm_pa_features())
 
 	# Try sysinfo
-	CopyNewFields(info, _get_cpu_info_from_sysinfo())
+	_copy_new_fields(info, _get_cpu_info_from_sysinfo())
 
 	# Try querying the CPU cpuid register
-	CopyNewFields(info, _get_cpu_info_from_cpuid())
+	_copy_new_fields(info, _get_cpu_info_from_cpuid())
 
 	return info
 
-# Make sure we are running on a supported system
-def _check_arch():
-	arch, bits = parse_arch(DataSource.raw_arch_string)
-	if not arch in ['X86_32', 'X86_64', 'ARM_7', 'ARM_8', 'PPC_64']:
-		raise Exception("py-cpuinfo currently only works on X86 and some PPC and ARM CPUs.")
+def get_cpu_info_json():
+	'''
+	Returns the CPU info by using the best sources of information for your OS.
+	Returns the result in a json string
+	'''
+
+	import json
+
+	output = None
+
+	# If running under pyinstaller, run normally
+	if getattr(sys, 'frozen', False):
+		info = _get_cpu_info_internal()
+		output = json.dumps(info)
+		output = "{0}".format(output)
+	# if not running under pyinstaller, run in another process.
+	# This is done because multiprocesing has a design flaw that
+	# causes non main programs to run multiple times on Windows.
+	else:
+		from subprocess import Popen, PIPE
+
+		command = [sys.executable, __file__, '--json']
+		p1 = Popen(command, stdout=PIPE, stderr=PIPE, stdin=PIPE)
+		output = p1.communicate()[0]
+
+		if p1.returncode != 0:
+			return "{}"
+
+		if not IS_PY2:
+			output = output.decode(encoding='UTF-8')
+
+	return output
+
+def get_cpu_info():
+	'''
+	Returns the CPU info by using the best sources of information for your OS.
+	Returns the result in a dict
+	'''
+
+	import json
+
+	output = get_cpu_info_json()
+
+	# Convert JSON to Python with non unicode strings
+	output = json.loads(output, object_hook = _utf_to_str)
+
+	return output
 
 def main():
+	from argparse import ArgumentParser
+	import json
+
+	# Parse args
+	parser = ArgumentParser(description='Gets CPU info with pure Python 2 & 3')
+	parser.add_argument('--json', action='store_true', help='Return the info in JSON format')
+	args = parser.parse_args()
+
 	try:
 		_check_arch()
 	except Exception as err:
 		sys.stderr.write(str(err) + "\n")
 		sys.exit(1)
 
-	info = get_cpu_info()
-	if info:
-		print('python version: {0}'.format(info.get('python_version', '')))
-		print('cpuinfo version: {0}'.format(info.get('cpuinfo_version', '')))
+	info = _get_cpu_info_internal()
+
+	if not info:
+		sys.stderr.write("Failed to find cpu info\n")
+		sys.exit(1)
+
+	if args.json:
+		print(json.dumps(info))
+	else:
+		print('Python Version: {0}'.format(info.get('python_version', '')))
+		print('Cpuinfo Version: {0}'.format(info.get('cpuinfo_version', '')))
 		print('Vendor ID: {0}'.format(info.get('vendor_id', '')))
 		print('Hardware Raw: {0}'.format(info.get('hardware', '')))
 		print('Brand: {0}'.format(info.get('brand', '')))
@@ -2197,14 +2249,9 @@ def main():
 		print('Extended Model: {0}'.format(info.get('extended_model', '')))
 		print('Extended Family: {0}'.format(info.get('extended_family', '')))
 		print('Flags: {0}'.format(', '.join(info.get('flags', ''))))
-	else:
-		sys.stderr.write("Failed to find cpu info\n")
-		sys.exit(1)
 
 
 if __name__ == '__main__':
-	from multiprocessing import freeze_support
-	freeze_support()
 	main()
 else:
 	_check_arch()
diff --git a/py_cpuinfo.egg-info/PKG-INFO b/py_cpuinfo.egg-info/PKG-INFO
index 17c18f8..8495ee5 100644
--- a/py_cpuinfo.egg-info/PKG-INFO
+++ b/py_cpuinfo.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: py-cpuinfo
-Version: 4.0.0
+Version: 5.0.0
 Summary: Get CPU info with pure Python 2 & 3
 Home-page: https://github.com/workhorsy/py-cpuinfo
 Author: Matthew Brennan Jones
diff --git a/py_cpuinfo.egg-info/SOURCES.txt b/py_cpuinfo.egg-info/SOURCES.txt
index 5069495..908a413 100644
--- a/py_cpuinfo.egg-info/SOURCES.txt
+++ b/py_cpuinfo.egg-info/SOURCES.txt
@@ -14,6 +14,7 @@ py_cpuinfo.egg-info/entry_points.txt
 py_cpuinfo.egg-info/top_level.txt
 tests/helpers.py
 tests/test_actual.py
+tests/test_cli.py
 tests/test_cpuid.py
 tests/test_example.py
 tests/test_free_bsd_11_x86_64.py
diff --git a/setup.py b/setup.py
index 1ad5b28..2da6fb9 100644
--- a/setup.py
+++ b/setup.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2014-2018, Matthew Brennan Jones <matthew.brennan.jones@gmail.com>
+# Copyright (c) 2014-2019, Matthew Brennan Jones <matthew.brennan.jones@gmail.com>
 # Py-cpuinfo gets CPU info with pure Python 2 & 3
 # It uses the MIT License
 # It is hosted at: https://github.com/workhorsy/py-cpuinfo
@@ -11,7 +11,7 @@ with open(os.path.join(os.getcwd(), 'README.rst'), 'r') as f:
 
 setup(
     name = "py-cpuinfo",
-    version = "4.0.0",
+    version = "5.0.0",
     author = "Matthew Brennan Jones",
     author_email = "matthew.brennan.jones@gmail.com",
     description = "Get CPU info with pure Python 2 & 3",
diff --git a/test_suite.py b/test_suite.py
index ba8d18f..f2fe6e9 100644
--- a/test_suite.py
+++ b/test_suite.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
-# Copyright (c) 2014-2018, Matthew Brennan Jones <matthew.brennan.jones@gmail.com>
+# Copyright (c) 2014-2019, Matthew Brennan Jones <matthew.brennan.jones@gmail.com>
 # Py-cpuinfo gets CPU info with pure Python 2 & 3
 # It uses the MIT License
 # It is hosted at: https://github.com/workhorsy/py-cpuinfo
@@ -63,6 +63,7 @@ from test_windows_8_x86_64 import TestWindows_8_X86_64
 from test_windows_10_x86_64 import TestWindows_10_X86_64
 from test_cpuid import TestCPUID
 from test_actual import TestActual
+from test_cli import TestCLI
 
 if __name__ == '__main__':
 	def logger(msg):
@@ -99,7 +100,8 @@ if __name__ == '__main__':
 		TestWindows_8_X86_64,
 		TestWindows_10_X86_64,
 		TestCPUID,
-		TestActual
+		TestActual,
+		TestCLI
 	]
 
 	# Add the tests to the suite
diff --git a/tests/helpers.py b/tests/helpers.py
index c510564..a29b344 100644
--- a/tests/helpers.py
+++ b/tests/helpers.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
-# Copyright (c) 2014-2018, Matthew Brennan Jones <matthew.brennan.jones@gmail.com>
+# Copyright (c) 2014-2019, Matthew Brennan Jones <matthew.brennan.jones@gmail.com>
 # Py-cpuinfo gets CPU info with pure Python 2 & 3
 # It uses the MIT License
 # It is hosted at: https://github.com/workhorsy/py-cpuinfo
@@ -26,7 +26,6 @@
 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 
-import platform
 
 class EmptyDataSource(object):
 	@staticmethod
@@ -78,6 +77,8 @@ class EmptyDataSource(object):
 		return False
 
 def get_os_type():
+	import platform
+
 	os_type = 'Unknown'
 
 	# Figure out the general OS type
diff --git a/tests/test_cli.py b/tests/test_cli.py
new file mode 100644
index 0000000..991f9c8
--- /dev/null
+++ b/tests/test_cli.py
@@ -0,0 +1,47 @@
+
+
+import unittest
+from cpuinfo import *
+import helpers
+
+
+
+class TestCLI(unittest.TestCase):
+	def setUp(self):
+		helpers.backup_data_source(cpuinfo)
+
+	def tearDown(self):
+		helpers.restore_data_source(cpuinfo)
+
+	def test_json(self):
+		from subprocess import Popen, PIPE
+		import json
+
+		command = [sys.executable, 'cpuinfo/cpuinfo.py', '--json']
+		p1 = Popen(command, stdout=PIPE, stderr=PIPE, stdin=PIPE)
+		output = p1.communicate()[0]
+
+		self.assertEqual(0, p1.returncode)
+
+		if not IS_PY2:
+			output = output.decode(encoding='UTF-8')
+
+		info = json.loads(output, object_hook = cpuinfo._utf_to_str)
+
+		self.assertEqual(list(cpuinfo.CPUINFO_VERSION), info['cpuinfo_version'])
+
+	def test_default(self):
+		from subprocess import Popen, PIPE
+
+		command = [sys.executable, 'cpuinfo/cpuinfo.py']
+		p1 = Popen(command, stdout=PIPE, stderr=PIPE, stdin=PIPE)
+		output = p1.communicate()[0]
+
+		self.assertEqual(0, p1.returncode)
+
+		if not IS_PY2:
+			output = output.decode(encoding='UTF-8')
+
+		version = output.split('Cpuinfo Version: ')[1].split('\n')[0].strip()
+
+		self.assertEqual(str(cpuinfo.CPUINFO_VERSION), version)
diff --git a/tests/test_example.py b/tests/test_example.py
index 75ef1b7..32b0e3b 100644
--- a/tests/test_example.py
+++ b/tests/test_example.py
@@ -141,4 +141,4 @@ class TestExample(unittest.TestCase):
 
 		#self.assertEqual({}, cpuinfo._get_cpu_info_from_cpuid())
 
-		#self.assertEqual({}, cpuinfo.get_cpu_info())
+		#self.assertEqual({}, cpuinfo._get_cpu_info_internal())
diff --git a/tests/test_free_bsd_11_x86_64.py b/tests/test_free_bsd_11_x86_64.py
index 39e3337..4b8ad80 100644
--- a/tests/test_free_bsd_11_x86_64.py
+++ b/tests/test_free_bsd_11_x86_64.py
@@ -81,7 +81,7 @@ class TestFreeBSD_11_X86_64(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(16, len(cpuinfo.get_cpu_info()))
+		self.assertEqual(16, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_dmesg(self):
 		info = cpuinfo._get_cpu_info_from_dmesg()
@@ -130,7 +130,7 @@ class TestFreeBSD_11_X86_64(unittest.TestCase):
 		)
 
 	def test_all(self):
-		info = cpuinfo.get_cpu_info()
+		info = cpuinfo._get_cpu_info_internal()
 
 		self.assertEqual('GenuineIntel', info['vendor_id'])
 		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand'])
diff --git a/tests/test_haiku_x86_32.py b/tests/test_haiku_x86_32.py
index fbe20d7..f235eb1 100644
--- a/tests/test_haiku_x86_32.py
+++ b/tests/test_haiku_x86_32.py
@@ -74,7 +74,7 @@ class TestHaiku_x86_32(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(9, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(15, len(cpuinfo.get_cpu_info()))
+		self.assertEqual(15, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_sysinfo(self):
 		info = cpuinfo._get_cpu_info_from_sysinfo()
@@ -97,7 +97,7 @@ class TestHaiku_x86_32(unittest.TestCase):
 		)
 
 	def test_all(self):
-		info = cpuinfo.get_cpu_info()
+		info = cpuinfo._get_cpu_info_internal()
 
 		self.assertEqual('Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz', info['brand'])
 		self.assertEqual('2.9300 GHz', info['hz_advertised'])
diff --git a/tests/test_haiku_x86_64.py b/tests/test_haiku_x86_64.py
index 83f2ef9..e44d0b2 100644
--- a/tests/test_haiku_x86_64.py
+++ b/tests/test_haiku_x86_64.py
@@ -74,7 +74,7 @@ class TestHaiku_x86_64(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(9, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(15, len(cpuinfo.get_cpu_info()))
+		self.assertEqual(15, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_sysinfo(self):
 		info = cpuinfo._get_cpu_info_from_sysinfo()
@@ -98,7 +98,7 @@ class TestHaiku_x86_64(unittest.TestCase):
 		)
 
 	def test_all(self):
-		info = cpuinfo.get_cpu_info()
+		info = cpuinfo._get_cpu_info_internal()
 
 		self.assertEqual('Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz', info['brand'])
 		self.assertEqual('2.9300 GHz', info['hz_advertised'])
diff --git a/tests/test_invalid_cpu.py b/tests/test_invalid_cpu.py
index baa8112..2f6843d 100644
--- a/tests/test_invalid_cpu.py
+++ b/tests/test_invalid_cpu.py
@@ -22,7 +22,7 @@ class TestInvalidCPU(unittest.TestCase):
 
 	def test_arch_parse_unknown(self):
 		# If the arch is unknown, the result should be null
-		arch, bits = cpuinfo.parse_arch(DataSource.raw_arch_string)
+		arch, bits = cpuinfo._parse_arch(DataSource.raw_arch_string)
 		self.assertIsNone(arch)
 		self.assertIsNone(bits)
 
diff --git a/tests/test_linux_aarch64_64.py b/tests/test_linux_aarch64_64.py
index b980a98..20779f0 100644
--- a/tests/test_linux_aarch64_64.py
+++ b/tests/test_linux_aarch64_64.py
@@ -126,7 +126,7 @@ class TestLinux_Aarch_64(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(10, len(cpuinfo.get_cpu_info()))
+		self.assertEqual(10, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_lscpu(self):
 		info = cpuinfo._get_cpu_info_from_lscpu()
@@ -150,7 +150,7 @@ class TestLinux_Aarch_64(unittest.TestCase):
 
 	@unittest.skip("FIXME: This fails because it does not have a way to get CPU brand string and Hz.")
 	def test_all(self):
-		info = cpuinfo.get_cpu_info()
+		info = cpuinfo._get_cpu_info_internal()
 
 		self.assertEqual('', info['vendor_id'])
 		self.assertEqual('FIXME', info['hardware'])
diff --git a/tests/test_linux_beagle_bone_arm.py b/tests/test_linux_beagle_bone_arm.py
index 36ad5a1..d38eae4 100644
--- a/tests/test_linux_beagle_bone_arm.py
+++ b/tests/test_linux_beagle_bone_arm.py
@@ -87,7 +87,7 @@ class TestLinux_BeagleBone(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(13, len(cpuinfo.get_cpu_info()))
+		self.assertEqual(13, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_cpufreq_info(self):
 		info = cpuinfo._get_cpu_info_from_cpufreq_info()
@@ -110,7 +110,7 @@ class TestLinux_BeagleBone(unittest.TestCase):
 		)
 
 	def test_all(self):
-		info = cpuinfo.get_cpu_info()
+		info = cpuinfo._get_cpu_info_internal()
 
 		self.assertEqual('BCM2708', info['hardware'])
 		self.assertEqual('ARMv6-compatible processor rev 7 (v6l)', info['brand'])
diff --git a/tests/test_linux_debian_8_5_x86_64.py b/tests/test_linux_debian_8_5_x86_64.py
index 6c8a5cc..a9a3bbd 100644
--- a/tests/test_linux_debian_8_5_x86_64.py
+++ b/tests/test_linux_debian_8_5_x86_64.py
@@ -461,7 +461,7 @@ class TestLinuxDebian_8_5_X86_64(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(20, len(cpuinfo.get_cpu_info()))
+		self.assertEqual(20, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_lscpu(self):
 		info = cpuinfo._get_cpu_info_from_lscpu()
@@ -523,7 +523,7 @@ class TestLinuxDebian_8_5_X86_64(unittest.TestCase):
 		)
 
 	def test_all(self):
-		info = cpuinfo.get_cpu_info()
+		info = cpuinfo._get_cpu_info_internal()
 
 		self.assertEqual('GenuineIntel', info['vendor_id'])
 		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand'])
diff --git a/tests/test_linux_debian_8_7_1_ppc64le.py b/tests/test_linux_debian_8_7_1_ppc64le.py
index 395dffc..d601b6b 100644
--- a/tests/test_linux_debian_8_7_1_ppc64le.py
+++ b/tests/test_linux_debian_8_7_1_ppc64le.py
@@ -431,7 +431,7 @@ class TestLinuxDebian_8_7_1_ppc64le(unittest.TestCase):
 		self.assertEqual(1, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(14, len(cpuinfo.get_cpu_info()))
+		self.assertEqual(14, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_lscpu(self):
 		info = cpuinfo._get_cpu_info_from_lscpu()
@@ -456,7 +456,7 @@ class TestLinuxDebian_8_7_1_ppc64le(unittest.TestCase):
 		self.assertEqual((1000000000, 0), info['hz_actual_raw'])
 
 	def test_all(self):
-		info = cpuinfo.get_cpu_info()
+		info = cpuinfo._get_cpu_info_internal()
 
 		self.assertEqual('POWER7 (raw), altivec supported', info['brand'])
 		self.assertEqual('1.0000 GHz', info['hz_advertised'])
diff --git a/tests/test_linux_debian_8_x86_64.py b/tests/test_linux_debian_8_x86_64.py
index 54759f2..fd74c44 100644
--- a/tests/test_linux_debian_8_x86_64.py
+++ b/tests/test_linux_debian_8_x86_64.py
@@ -75,7 +75,7 @@ class TestLinuxDebian_8_X86_64(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(17, len(cpuinfo.get_cpu_info()))
+		self.assertEqual(17, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_proc_cpuinfo(self):
 		info = cpuinfo._get_cpu_info_from_proc_cpuinfo()
@@ -102,7 +102,7 @@ class TestLinuxDebian_8_X86_64(unittest.TestCase):
 		)
 
 	def test_all(self):
-		info = cpuinfo.get_cpu_info()
+		info = cpuinfo._get_cpu_info_internal()
 
 		self.assertEqual('GenuineIntel', info['vendor_id'])
 		self.assertEqual('Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz', info['brand'])
diff --git a/tests/test_linux_fedora_24_ppc64le.py b/tests/test_linux_fedora_24_ppc64le.py
index 4d414db..2e081b9 100644
--- a/tests/test_linux_fedora_24_ppc64le.py
+++ b/tests/test_linux_fedora_24_ppc64le.py
@@ -364,7 +364,7 @@ class TestLinuxFedora_24_ppc64le(unittest.TestCase):
 		self.assertEqual(1, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(14, len(cpuinfo.get_cpu_info()))
+		self.assertEqual(14, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_lscpu(self):
 		info = cpuinfo._get_cpu_info_from_lscpu()
@@ -391,7 +391,7 @@ class TestLinuxFedora_24_ppc64le(unittest.TestCase):
 		self.assertEqual((3425000000, 0), info['hz_actual_raw'])
 
 	def test_all(self):
-		info = cpuinfo.get_cpu_info()
+		info = cpuinfo._get_cpu_info_internal()
 
 		self.assertEqual('POWER8E (raw), altivec supported', info['brand'])
 		self.assertEqual('3.4250 GHz', info['hz_advertised'])
diff --git a/tests/test_linux_fedora_24_x86_64.py b/tests/test_linux_fedora_24_x86_64.py
index e98ffcd..fb3bdc7 100644
--- a/tests/test_linux_fedora_24_x86_64.py
+++ b/tests/test_linux_fedora_24_x86_64.py
@@ -461,7 +461,7 @@ class TestLinuxFedora_24_X86_64(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(20, len(cpuinfo.get_cpu_info()))
+		self.assertEqual(20, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_lscpu(self):
 		info = cpuinfo._get_cpu_info_from_lscpu()
@@ -524,7 +524,7 @@ class TestLinuxFedora_24_X86_64(unittest.TestCase):
 		)
 
 	def test_all(self):
-		info = cpuinfo.get_cpu_info()
+		info = cpuinfo._get_cpu_info_internal()
 
 		self.assertEqual('GenuineIntel', info['vendor_id'])
 		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand'])
diff --git a/tests/test_linux_gentoo_2_2_x86_64.py b/tests/test_linux_gentoo_2_2_x86_64.py
index 50d206b..9a4cbb3 100644
--- a/tests/test_linux_gentoo_2_2_x86_64.py
+++ b/tests/test_linux_gentoo_2_2_x86_64.py
@@ -464,7 +464,7 @@ class TestLinuxGentoo_2_2_X86_64(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(20, len(cpuinfo.get_cpu_info()))
+		self.assertEqual(20, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_lscpu(self):
 		info = cpuinfo._get_cpu_info_from_lscpu()
@@ -536,7 +536,7 @@ class TestLinuxGentoo_2_2_X86_64(unittest.TestCase):
 		)
 
 	def test_all(self):
-		info = cpuinfo.get_cpu_info()
+		info = cpuinfo._get_cpu_info_internal()
 
 		self.assertEqual('GenuineIntel', info['vendor_id'])
 		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand'])
diff --git a/tests/test_linux_odroid_c2_aarch64.py b/tests/test_linux_odroid_c2_aarch64.py
index 7d67f5d..da94b92 100644
--- a/tests/test_linux_odroid_c2_aarch64.py
+++ b/tests/test_linux_odroid_c2_aarch64.py
@@ -173,7 +173,7 @@ class TestLinux_Odroid_C2_Aarch_64(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(12, len(cpuinfo.get_cpu_info()))
+		self.assertEqual(12, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_cpufreq_info(self):
 		info = cpuinfo._get_cpu_info_from_cpufreq_info()
@@ -202,7 +202,7 @@ class TestLinux_Odroid_C2_Aarch_64(unittest.TestCase):
 		)
 
 	def test_all(self):
-		info = cpuinfo.get_cpu_info()
+		info = cpuinfo._get_cpu_info_internal()
 
 		self.assertEqual('ODROID-C2', info['hardware'])
 		self.assertEqual('1.5400 GHz', info['hz_advertised'])
diff --git a/tests/test_linux_odroid_xu3_arm_32.py b/tests/test_linux_odroid_xu3_arm_32.py
index 28632d5..52291ea 100644
--- a/tests/test_linux_odroid_xu3_arm_32.py
+++ b/tests/test_linux_odroid_xu3_arm_32.py
@@ -264,7 +264,7 @@ class TestLinux_Odroid_XU3_arm_32(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(13, len(cpuinfo.get_cpu_info()))
+		self.assertEqual(13, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_cpufreq_info(self):
 		info = cpuinfo._get_cpu_info_from_cpufreq_info()
@@ -296,7 +296,7 @@ class TestLinux_Odroid_XU3_arm_32(unittest.TestCase):
 		)
 
 	def test_all(self):
-		info = cpuinfo.get_cpu_info()
+		info = cpuinfo._get_cpu_info_internal()
 
 		self.assertEqual('ARMv7 Processor rev 3 (v7l)', info['brand'])
 		self.assertEqual('ODROID-XU3', info['hardware'])
diff --git a/tests/test_linux_raspberry_pi_model_b_arm.py b/tests/test_linux_raspberry_pi_model_b_arm.py
index 1ef8d02..ecc7114 100644
--- a/tests/test_linux_raspberry_pi_model_b_arm.py
+++ b/tests/test_linux_raspberry_pi_model_b_arm.py
@@ -81,7 +81,7 @@ class TestLinux_RaspberryPiModelB(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(13, len(cpuinfo.get_cpu_info()))
+		self.assertEqual(13, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_lscpu(self):
 		info = cpuinfo._get_cpu_info_from_lscpu()
@@ -104,7 +104,7 @@ class TestLinux_RaspberryPiModelB(unittest.TestCase):
 		)
 
 	def test_all(self):
-		info = cpuinfo.get_cpu_info()
+		info = cpuinfo._get_cpu_info_internal()
 
 		self.assertEqual('BCM2708', info['hardware'])
 		self.assertEqual('ARMv6-compatible processor rev 7 (v6l)', info['brand'])
diff --git a/tests/test_linux_rhel_7_3_ppc64le.py b/tests/test_linux_rhel_7_3_ppc64le.py
index 8daa65c..7f34206 100644
--- a/tests/test_linux_rhel_7_3_ppc64le.py
+++ b/tests/test_linux_rhel_7_3_ppc64le.py
@@ -342,7 +342,7 @@ class TestLinuxRHEL_7_3_ppc64le(unittest.TestCase):
 		self.assertEqual(1, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(14, len(cpuinfo.get_cpu_info()))
+		self.assertEqual(14, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_lscpu(self):
 		info = cpuinfo._get_cpu_info_from_lscpu()
@@ -367,7 +367,7 @@ class TestLinuxRHEL_7_3_ppc64le(unittest.TestCase):
 		self.assertEqual((3425000000, 0), info['hz_actual_raw'])
 
 	def test_all(self):
-		info = cpuinfo.get_cpu_info()
+		info = cpuinfo._get_cpu_info_internal()
 
 		self.assertEqual('POWER8E (raw), altivec supported', info['brand'])
 		self.assertEqual('3.4250 GHz', info['hz_advertised'])
diff --git a/tests/test_linux_ubuntu_16_04_x86_64.py b/tests/test_linux_ubuntu_16_04_x86_64.py
index 2c115fe..13dd60a 100644
--- a/tests/test_linux_ubuntu_16_04_x86_64.py
+++ b/tests/test_linux_ubuntu_16_04_x86_64.py
@@ -465,7 +465,7 @@ class TestLinuxUbuntu_16_04_X86_64(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(20, len(cpuinfo.get_cpu_info()))
+		self.assertEqual(20, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_lscpu(self):
 		info = cpuinfo._get_cpu_info_from_lscpu()
@@ -546,7 +546,7 @@ class TestLinuxUbuntu_16_04_X86_64(unittest.TestCase):
 		)
 
 	def test_all(self):
-		info = cpuinfo.get_cpu_info()
+		info = cpuinfo._get_cpu_info_internal()
 
 		self.assertEqual('GenuineIntel', info['vendor_id'])
 		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand'])
diff --git a/tests/test_osx_10_12_x86_64.py b/tests/test_osx_10_12_x86_64.py
index 6654487..b58d637 100644
--- a/tests/test_osx_10_12_x86_64.py
+++ b/tests/test_osx_10_12_x86_64.py
@@ -108,7 +108,7 @@ class TestOSX_10_12(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(17, len(cpuinfo.get_cpu_info()))
+		self.assertEqual(17, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_sysctl(self):
 		info = cpuinfo._get_cpu_info_from_sysctl()
@@ -140,7 +140,7 @@ class TestOSX_10_12(unittest.TestCase):
 		)
 
 	def test_all(self):
-		info = cpuinfo.get_cpu_info()
+		info = cpuinfo._get_cpu_info_internal()
 
 		self.assertEqual('GenuineIntel', info['vendor_id'])
 		self.assertEqual('Intel(R) Core(TM) i5-2557M CPU @ 1.70GHz', info['brand'])
diff --git a/tests/test_osx_10_9_x86_64.py b/tests/test_osx_10_9_x86_64.py
index 49199c7..b247813 100644
--- a/tests/test_osx_10_9_x86_64.py
+++ b/tests/test_osx_10_9_x86_64.py
@@ -88,7 +88,7 @@ class TestOSX_10_9(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(17, len(cpuinfo.get_cpu_info()))
+		self.assertEqual(17, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_sysctl(self):
 		info = cpuinfo._get_cpu_info_from_sysctl()
@@ -116,7 +116,7 @@ class TestOSX_10_9(unittest.TestCase):
 		)
 
 	def test_all(self):
-		info = cpuinfo.get_cpu_info()
+		info = cpuinfo._get_cpu_info_internal()
 
 		self.assertEqual('GenuineIntel', info['vendor_id'])
 		self.assertEqual('Intel(R) Core(TM) i5-4440 CPU @ 3.10GHz', info['brand'])
diff --git a/tests/test_parse_cpu_string.py b/tests/test_parse_cpu_string.py
index c472163..3310163 100644
--- a/tests/test_parse_cpu_string.py
+++ b/tests/test_parse_cpu_string.py
@@ -63,31 +63,31 @@ class TestParseCPUString(unittest.TestCase):
 		scale, hz_brand = cpuinfo._get_hz_string_from_brand('Intel(R) Pentium(R) CPU G640 @ 2.80GHz')
 		self.assertEqual(9, scale)
 		self.assertEqual('2.8', hz_brand)
-		self.assertEqual('2.8000 GHz', to_friendly_hz(hz_brand, scale))
+		self.assertEqual('2.8000 GHz', cpuinfo._to_friendly_hz(hz_brand, scale))
 
 		scale, hz_brand = cpuinfo._get_hz_string_from_brand('Intel(R) Pentium(R) CPU @ 1.20MHz')
 		self.assertEqual(6, scale)
 		self.assertEqual('1.2', hz_brand)
-		self.assertEqual('1.2000 MHz', to_friendly_hz(hz_brand, scale))
+		self.assertEqual('1.2000 MHz', cpuinfo._to_friendly_hz(hz_brand, scale))
 
 		scale, hz_brand = cpuinfo._get_hz_string_from_brand('Intel(R) Pentium(R) D CPU 3.20GHz')
 		self.assertEqual(9, scale)
 		self.assertEqual('3.2', hz_brand)
-		self.assertEqual('3.2000 GHz', to_friendly_hz(hz_brand, scale))
+		self.assertEqual('3.2000 GHz', cpuinfo._to_friendly_hz(hz_brand, scale))
 
 	def test_to_raw_hz(self):
 		scale, hz_brand = cpuinfo._get_hz_string_from_brand('Intel(R) Pentium(R) CPU G640 @ 2.80GHz')
 		self.assertEqual(9, scale)
 		self.assertEqual('2.8', hz_brand)
-		self.assertEqual((2800000000, 0), to_raw_hz(hz_brand, scale))
+		self.assertEqual((2800000000, 0), cpuinfo._to_raw_hz(hz_brand, scale))
 
 		scale, hz_brand = cpuinfo._get_hz_string_from_brand('Intel(R) Pentium(R) CPU @ 1.20MHz')
 		self.assertEqual(6, scale)
 		self.assertEqual('1.2', hz_brand)
-		self.assertEqual((1200000, 0), to_raw_hz(hz_brand, scale))
+		self.assertEqual((1200000, 0), cpuinfo._to_raw_hz(hz_brand, scale))
 
 		# NOTE: No @ symbol
 		scale, hz_brand = cpuinfo._get_hz_string_from_brand('Intel(R) Pentium(R) D CPU 3.20GHz')
 		self.assertEqual(9, scale)
 		self.assertEqual('3.2', hz_brand)
-		self.assertEqual((3200000000, 0), to_raw_hz(hz_brand, scale))
+		self.assertEqual((3200000000, 0), cpuinfo._to_raw_hz(hz_brand, scale))
diff --git a/tests/test_parse_errors.py b/tests/test_parse_errors.py
index 0e6757b..0d24d02 100644
--- a/tests/test_parse_errors.py
+++ b/tests/test_parse_errors.py
@@ -151,4 +151,4 @@ class TestParseErrors(unittest.TestCase):
 
 		#self.assertEqual({}, cpuinfo._get_cpu_info_from_cpuid())
 
-		#self.assertEqual({}, cpuinfo.get_cpu_info())
+		#self.assertEqual({}, cpuinfo._get_cpu_info_internal())
diff --git a/tests/test_pcbsd_10_x86_64.py b/tests/test_pcbsd_10_x86_64.py
index 5ecca3c..17653c6 100644
--- a/tests/test_pcbsd_10_x86_64.py
+++ b/tests/test_pcbsd_10_x86_64.py
@@ -62,7 +62,7 @@ class TestPCBSD(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(12, len(cpuinfo.get_cpu_info()))
+		self.assertEqual(12, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_dmesg(self):
 		info = cpuinfo._get_cpu_info_from_dmesg()
@@ -83,7 +83,7 @@ class TestPCBSD(unittest.TestCase):
 		)
 
 	def test_all(self):
-		info = cpuinfo.get_cpu_info()
+		info = cpuinfo._get_cpu_info_internal()
 
 		self.assertEqual('Intel(R) Core(TM) i5-4440 CPU @ 3.10GHz', info['brand'])
 		self.assertEqual('3.1000 GHz', info['hz_advertised'])
diff --git a/tests/test_solaris_11_x86_32.py b/tests/test_solaris_11_x86_32.py
index 346e220..2acc448 100644
--- a/tests/test_solaris_11_x86_32.py
+++ b/tests/test_solaris_11_x86_32.py
@@ -102,7 +102,7 @@ class TestSolaris(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(16, len(cpuinfo.get_cpu_info()))
+		self.assertEqual(16, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_kstat(self):
 		info = cpuinfo._get_cpu_info_from_kstat()
@@ -124,7 +124,7 @@ class TestSolaris(unittest.TestCase):
 		)
 
 	def test_all(self):
-		info = cpuinfo.get_cpu_info()
+		info = cpuinfo._get_cpu_info_internal()
 
 		self.assertEqual('GenuineIntel', info['vendor_id'])
 		self.assertEqual('Intel(r) Core(tm) i7 CPU         870  @ 2.93GHz', info['brand'])
diff --git a/tests/test_windows_10_x86_64.py b/tests/test_windows_10_x86_64.py
index efde133..6f87e78 100644
--- a/tests/test_windows_10_x86_64.py
+++ b/tests/test_windows_10_x86_64.py
@@ -78,7 +78,7 @@ class TestWindows_10_X86_64(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(18, len(cpuinfo.get_cpu_info()))
+		self.assertEqual(18, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_wmic(self):
 		info = cpuinfo._get_cpu_info_from_wmic()
@@ -118,7 +118,7 @@ class TestWindows_10_X86_64(unittest.TestCase):
 		)
 
 	def test_all(self):
-		info = cpuinfo.get_cpu_info()
+		info = cpuinfo._get_cpu_info_internal()
 
 		self.assertEqual('GenuineIntel', info['vendor_id'])
 		self.assertEqual('Intel(R) Core(TM) i5-4300U CPU @ 1.90GHz', info['brand'])
diff --git a/tests/test_windows_8_x86_64.py b/tests/test_windows_8_x86_64.py
index 8ce5664..5e2b284 100644
--- a/tests/test_windows_8_x86_64.py
+++ b/tests/test_windows_8_x86_64.py
@@ -78,7 +78,7 @@ class TestWindows_8_X86_64(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(18, len(cpuinfo.get_cpu_info()))
+		self.assertEqual(18, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_wmic(self):
 		info = cpuinfo._get_cpu_info_from_wmic()
@@ -118,7 +118,7 @@ class TestWindows_8_X86_64(unittest.TestCase):
 		)
 
 	def test_all(self):
-		info = cpuinfo.get_cpu_info()
+		info = cpuinfo._get_cpu_info_internal()
 
 		self.assertEqual('GenuineIntel', info['vendor_id'])
 		self.assertEqual('Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz', info['brand'])
-- 
GitLab