diff --git a/SConstruct b/SConstruct
index e30f6df284eb488fa55e7edb4ed8bcbe666705d5..81bc849b15e11c8df5875d4cfdc39cb8d0757169 100644
--- a/SConstruct
+++ b/SConstruct
@@ -95,9 +95,15 @@ env["ENV"].update(x for x in os.environ.items() if x[0].startswith("CCC_"))
 #env.Append(CPPPATH=os.path.join('#', "hammer"))
 
 testruns = []
+targets = ["$libpath",
+           "$incpath",
+           "$parsersincpath",
+           "$backendsincpath",
+           "$pkgconfigpath"]
 
 Export('env')
 Export('testruns')
+Export('targets')
 
 if not GetOption("in_place"):
     env['BUILD_BASE'] = 'build/$VARIANT'
@@ -108,12 +114,6 @@ else:
     lib = env.SConscript(["src/SConscript"])
     env.Alias(env.SConscript(["examples/SConscript"]))
 
-#env.Command('test', '$BUILD_BASE/src/test_suite', 'env LD_LIBRARY_PATH=$BUILD_BASE/src $SOURCE')
-
 env.Alias("test", testruns)
 
-env.Alias("install", "$libpath")
-env.Alias("install", "$incpath")
-env.Alias("install", "$parsersincpath")
-env.Alias("install", "$backendsincpath")
-env.Alias("install", "$pkgconfigpath")
+env.Alias("install", targets)
diff --git a/src/bindings/python/README.md b/src/bindings/python/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..bdbf95e253a7d415fdf52c398607177ae0cb2e4c
--- /dev/null
+++ b/src/bindings/python/README.md
@@ -0,0 +1 @@
+The distutils script in this directory is meant to be invoked from scons. It will work if you build it here (`python setup.py build_ext`, optionally `--inplace` as scons invokes it), but we haven't done much testing of it outside the build system and don't really intend to. YHBW.
\ No newline at end of file
diff --git a/src/bindings/python/SConscript b/src/bindings/python/SConscript
index 0f1e9a92e5215fcb03547a3e075411e36bf2a949..d91a942300a17def47bf3188c3fe34f82ccdf8d2 100644
--- a/src/bindings/python/SConscript
+++ b/src/bindings/python/SConscript
@@ -1,29 +1,23 @@
 # -*- python -*-
 import os, os.path
-Import('env libhammer_shared testruns')
+Import('env libhammer_shared testruns targets')
 
 pythonenv = env.Clone(IMPLICIT_COMMAND_DEPENDENCIES = 0)
 
-pythonenv.Append(CPPPATH = ['../../'])
-pythonenv.Append(CCFLAGS = ['-fpic', '-DSWIG', '-Wno-all', '-Wno-extra', '-Wno-error'])
-pythonenv.ParseConfig("pkg-config --cflags python")
-pythonenv.Append(LIBS = ['hammer'])
-pythonenv.Append(LIBPATH = ['../../'])
-pythonenv.Append(SWIGFLAGS = ['-DHAMMER_INTERNAL__NO_STDARG_H', '-Isrc/', '-python'])
-
-pythonenv.Command("hammer.i", "../swig/hammer.i", Copy("$TARGET", "$SOURCE"))
-
-swig = ['hammer.i']
-
-libhammer_python = pythonenv.SharedLibrary('hammer', swig, SHLIBPREFIX='_')
+swig = pythonenv.Command("hammer.i", "../swig/hammer.i", Copy("$TARGET", "$SOURCE"))
+setup = ['setup.py']
+pydir = os.path.join(env['BUILD_BASE'], 'src/bindings/python')
+libhammer_python = pythonenv.Command(['hammer.py', 'hammer_wrap.c'], [swig, setup], 'python ' + os.path.join(pydir, 'setup.py') + ' build_ext --inplace')
 Default(libhammer_python)
 
 pytestenv = pythonenv.Clone()
 pytestenv['ENV']['LD_LIBRARY_PATH'] = os.path.dirname(str(libhammer_shared[0]))
 pytests = ['hammer_tests.py']
-pytestexec = pytestenv.Command(['hammer.pyc', 'hammer_tests.pyc'], pytests + libhammer_python, "nosetests -vv $SOURCE")
+pytestexec = pytestenv.Command(['hammer.pyc', 'hammer_tests.pyc'], pytests + libhammer_python, "LD_LIBRARY_PATH=" + os.path.dirname(str(libhammer_shared[0])) + " nosetests -vv $SOURCE")
 pytest = Alias("testpython", [pytestexec], pytestexec)
 AlwaysBuild(pytest)
 testruns.append(pytest)
 
-
+pyinstallexec = pythonenv.Command(None, libhammer_python, 'python ' + os.path.join(pydir, 'setup.py ') + ' install')
+pyinstall = Alias("installpython", [pyinstallexec], pyinstallexec)
+targets.append(pyinstall)
diff --git a/src/bindings/python/setup.py b/src/bindings/python/setup.py
new file mode 100644
index 0000000000000000000000000000000000000000..308283c84f030bacb0ac55b7d64ca694c765fb40
--- /dev/null
+++ b/src/bindings/python/setup.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+
+"""
+setup.py for Hammer bindings
+"""
+import os, os.path, sys
+from distutils.core import setup, Extension
+
+invoked = os.getcwd()
+if (os.path.dirname(sys.argv[0]) != ''):
+    os.chdir(os.path.dirname(sys.argv[0]))
+
+setup(name="hammer",
+      version="0.9.0",
+      author="Upstanding Hackers, LLC",
+      author_email="hammer@upstandinghackers.com",
+      url="https://github.com/UpstandingHackers/hammer",
+      description="""The Hammer parser combinator library""",
+      ext_modules=[Extension('_hammer', ['hammer.i'],
+                             swig_opts=['-DHAMMER_INTERNAL__NO_STDARG_H',
+                                        '-I../../'],
+                             define_macros=[('SWIG', None)],
+                             depends=['allocator.h', 
+                                      'glue.h', 
+                                      'hammer.h',
+                                      'internal.h',],
+                             extra_compile_args=['-fPIC',
+                                                 '-std=gnu99',],
+                             include_dirs=['../../'],
+                             library_dirs=['../../'],
+                             libraries=['hammer'],)],
+      
+      py_modules=['hammer'],
+)
+
+os.chdir(invoked)