1#!/usr/bin/env python 2import os 3import subprocess 4import sys 5from distutils.core import Command 6from glob import glob 7try: 8 from setuptools import setup, Extension 9except ImportError: 10 from distutils.core import setup 11 from distutils.extension import Extension 12 13 14class TestCommand(Command): 15 """Hack for setup.py with implicit build_ext -i 16 """ 17 user_options = [] 18 19 def initialize_options(self): 20 self.rootdir = os.getcwd() 21 22 def finalize_options(self): 23 pass 24 25 def remove_ext(self): 26 """Remove extensions 27 28 All Python 2.x versions share the same library name. Remove the 29 file to fix version mismatch errors. 30 """ 31 for fname in os.listdir(self.rootdir): 32 if fname.endswith(("so", "dylib", "pyd", "sl")): 33 os.unlink(os.path.join(self.rootdir, fname)) 34 35 def get_lib_dirs(self): 36 """Get version, platform and configuration dependend lib dirs 37 38 Distutils caches the build command object on the distribution object. 39 We can retrieve the object to retrieve the paths to the directories 40 inside the build directory. 41 """ 42 build = self.distribution.command_obj["build"] 43 builddirs = set() 44 for attrname in 'build_platlib', 'build_lib', 'build_purelib': 45 builddir = getattr(build, attrname, None) 46 if not builddir: 47 continue 48 builddir = os.path.abspath(os.path.join(self.rootdir, builddir)) 49 if not os.path.isdir(builddir): 50 continue 51 builddirs.add(builddir) 52 return builddirs 53 54 def run(self): 55 self.remove_ext() 56 # force a build with build_ext 57 self.run_command("build") 58 # get lib dirs from build object 59 libdirs = self.get_lib_dirs() 60 # add lib dirs to Python's search path 61 env = os.environ.copy() 62 env["PYTHONPATH"] = os.pathsep.join(libdirs) 63 # and finally run the test command 64 errno = subprocess.check_call([sys.executable, "tests.py"], env=env) 65 raise SystemExit(errno) 66 67 68exts = [] 69sha3_depends = ["setup.py", "Modules/hashlib.h", "Modules/pymemsets.h"] 70sha3_depends.extend(glob("Modules/_sha3/kcp/*")) 71exts.append( 72 Extension( 73 "_pysha3", 74 ["Modules/_sha3/sha3module.c", "Modules/pymemsets.c"], 75 depends=sha3_depends, 76 define_macros=[("PY_WITH_KECCAK", "1")] 77 ) 78) 79 80long_description = [] 81 82with open("README.txt") as f: 83 long_description.append(f.read()) 84 85with open("CHANGES.txt") as f: 86 long_description.append(f.read()) 87 88 89setup( 90 name="pysha3", 91 version="1.0.2", 92 ext_modules=exts, 93 py_modules=["sha3"], 94 cmdclass={"test": TestCommand}, 95 author="Christian Heimes", 96 author_email="christian@python.org", 97 maintainer="Christian Heimes", 98 maintainer_email="christian@python.org", 99 url="https://github.com/tiran/pysha3", 100 keywords="sha3 sha-3 keccak hash", 101 platforms="POSIX, Windows", 102 license="PSFL (Keccak: CC0 1.0 Universal)", 103 description="SHA-3 (Keccak) for Python 2.7 - 3.5", 104 long_description="\n".join(long_description), 105 classifiers=[ 106 "Development Status :: 4 - Beta", 107 "Intended Audience :: Developers", 108 "License :: OSI Approved :: Python Software Foundation License", 109 "License :: CC0 1.0 Universal (CC0 1.0) Public Domain Dedication", 110 "Natural Language :: English", 111 "Operating System :: MacOS :: MacOS X", 112 "Operating System :: POSIX", 113 "Operating System :: POSIX :: BSD", 114 "Operating System :: POSIX :: Linux", 115 "Operating System :: Microsoft :: Windows", 116 "Programming Language :: C", 117 "Programming Language :: Python", 118 "Programming Language :: Python :: 2", 119 "Programming Language :: Python :: 2.7", 120 "Programming Language :: Python :: 3", 121 "Programming Language :: Python :: 3.4", 122 "Programming Language :: Python :: 3.5", 123 "Topic :: Security :: Cryptography", 124 ], 125) 126