diff --git a/.gitignore b/.gitignore index 3a19b6e..9ea93d6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +/src/version.py + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..b4ae245 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,7 @@ +[build-system] +requires = ["setuptools>=42", "wheel", "setuptools_scm[toml]>=3.4.3", "Cython"] +build-backend = "setuptools.build_meta" + +[tool.setuptools_scm] +write_to = "src/version.py" +write_to_template = "__version__ = \"{version}\"" diff --git a/setup.cfg b/setup.cfg index c7275e3..b750fb5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,16 +1,42 @@ +[metadata] +name = pymspack +version = 0.2.0 +author = Gaetan Crahay +author_email = gaetan@crahay.eu +license = BSD license +description = Python bindings to libmspack +keywords = pymspack +url = https://github.com/gcrahay/pymspack +long_description = file: README.rst, HISTORY.rst +long_description_content_type = text/x-rst + +classifiers = + Development Status :: 2 - Pre-Alpha + Intended Audience :: Developers + License :: OSI Approved :: BSD License + Natural Language :: English + Programming Language :: Python :: 2 + Programming Language :: Python :: 2.7 + Programming Language :: Python :: 3 + Programming Language :: Python :: 3.5 + Programming Language :: Python :: 3.6 + Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 + +[options] +package_dir = + pymspack = src +packages = pymspack +zip_safe = False +setup_requires = setuptools>=42; wheel; setuptools_scm[toml]>=3.4.3; Cython +include_package_data = True +tests_require = pytest + [bumpversion] current_version = 0.1.0 commit = True tag = True -[bumpversion:file:setup.py] -search = version='{current_version}' -replace = version='{new_version}' - -[bumpversion:file:pymspack/__init__.py] -search = __version__ = '{current_version}' -replace = __version__ = '{new_version}' - [wheel] universal = 1 diff --git a/setup.py b/setup.py index e1a35a0..d5974ab 100644 --- a/setup.py +++ b/setup.py @@ -6,54 +6,11 @@ try: from Cython.Build import cythonize - ext_modules = cythonize([Extension("pymspack.ext", ["src/ext.pyx"], libraries=["mspack"])]) + ext_modules = [Extension("pymspack.ext", ["src/ext.c"], libraries=["mspack"])] except ImportError: print("Yous should have Cython installed to build this package extension.") import sys sys.exit() - -with open('README.rst') as readme_file: - readme = readme_file.read() - -with open('HISTORY.rst') as history_file: - history = history_file.read() - -requirements = [ - # TODO: put package requirements here -] - -test_requirements = [ - 'pytest' -] - -setup( - name='pymspack', - version='0.2.0', - description="Python bindings to libmspack", - long_description=readme + '\n\n' + history, - author="Gaetan Crahay", - author_email='gaetan@crahay.eu', - url='https://github.com/gcrahay/pymspack', - include_package_data=True, - install_requires=requirements, - license="BSD license", - zip_safe=False, - keywords='pymspack', - setup_requires=['Cython', ], - classifiers=[ - 'Development Status :: 2 - Pre-Alpha', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: BSD License', - 'Natural Language :: English', - "Programming Language :: Python :: 2", - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.5', - ], - test_suite='tests', - tests_require=test_requirements, - ext_modules=ext_modules, - packages=['pymspack',], - package_dir={"pymspack": "src"}, -) +if __name__ == "__main__": + setup(ext_modules=ext_modules) diff --git a/src/__init__.py b/src/__init__.py index ec66790..831b8fe 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -1 +1,2 @@ +from .version import __version__ from .ext import * diff --git a/src/ext.pxd b/src/ext.pxd index 6344803..19c40c0 100644 --- a/src/ext.pxd +++ b/src/ext.pxd @@ -1,3 +1,4 @@ +#cython: language_level=3 cdef extern from "mspack.h": cdef struct mscab_decompressor: mscabd_cabinet * (*open) (mscab_decompressor *self, const char *filename) @@ -25,27 +26,27 @@ cdef extern from "mspack.h": cdef struct mspack_system: pass - cdef int MSCAB_ATTRIB_RDONLY - cdef int MSCAB_ATTRIB_HIDDEN - cdef int MSCAB_ATTRIB_SYSTEM - cdef int MSCAB_ATTRIB_ARCH - cdef int MSCAB_ATTRIB_EXEC - cdef int MSCAB_ATTRIB_UTF_NAME + cdef const int MSCAB_ATTRIB_RDONLY + cdef const int MSCAB_ATTRIB_HIDDEN + cdef const int MSCAB_ATTRIB_SYSTEM + cdef const int MSCAB_ATTRIB_ARCH + cdef const int MSCAB_ATTRIB_EXEC + cdef const int MSCAB_ATTRIB_UTF_NAME - cdef int MSPACK_ERR_OK - cdef int MSPACK_ERR_ARGS - cdef int MSPACK_ERR_OPEN - cdef int MSPACK_ERR_READ - cdef int MSPACK_ERR_WRITE - cdef int MSPACK_ERR_SEEK - cdef int MSPACK_ERR_NOMEMORY - cdef int MSPACK_ERR_SIGNATURE - cdef int MSPACK_ERR_DATAFORMAT - cdef int MSPACK_ERR_CHECKSUM - cdef int MSPACK_ERR_CRUNCH - cdef int MSPACK_ERR_DECRUNCH + cdef const int MSPACK_ERR_OK + cdef const int MSPACK_ERR_ARGS + cdef const int MSPACK_ERR_OPEN + cdef const int MSPACK_ERR_READ + cdef const int MSPACK_ERR_WRITE + cdef const int MSPACK_ERR_SEEK + cdef const int MSPACK_ERR_NOMEMORY + cdef const int MSPACK_ERR_SIGNATURE + cdef const int MSPACK_ERR_DATAFORMAT + cdef const int MSPACK_ERR_CHECKSUM + cdef const int MSPACK_ERR_CRUNCH + cdef const int MSPACK_ERR_DECRUNCH - int MSPACK_SYS_SELFTEST(int) + void MSPACK_SYS_SELFTEST(int) mscab_decompressor *mspack_create_cab_decompressor(mspack_system *sys) void mspack_destroy_cab_decompressor(mscab_decompressor *self) diff --git a/src/ext.pyx b/src/ext.pyx index 5498a6f..29e2245 100644 --- a/src/ext.pyx +++ b/src/ext.pyx @@ -1,6 +1,40 @@ +#cython: language_level=3 cimport ext from os import path as os_path -__version__ = "0.2.0" +from enum import IntEnum as PyIntEnum + +class MSPackError(PyIntEnum): + OK = MSPACK_ERR_OK + args = MSPACK_ERR_ARGS + open = MSPACK_ERR_OPEN + read = MSPACK_ERR_READ + write = MSPACK_ERR_WRITE + seek = MSPACK_ERR_SEEK + noMemory = MSPACK_ERR_NOMEMORY + signature = MSPACK_ERR_SIGNATURE + dataFormat = MSPACK_ERR_DATAFORMAT + checkSum = MSPACK_ERR_CHECKSUM + crunch = MSPACK_ERR_CRUNCH + decrunch = MSPACK_ERR_DECRUNCH + +exceptionClassMapping = { + MSPACK_ERR_ARGS: ValueError, + MSPACK_ERR_OPEN: IOError, + MSPACK_ERR_READ: IOError, + MSPACK_ERR_WRITE: IOError, + MSPACK_ERR_SEEK: IOError, + MSPACK_ERR_NOMEMORY: MemoryError, + MSPACK_ERR_SIGNATURE: ValueError, + MSPACK_ERR_DATAFORMAT: ValueError, + MSPACK_ERR_CHECKSUM: RuntimeError, + MSPACK_ERR_CRUNCH: RuntimeError, + MSPACK_ERR_DECRUNCH: RuntimeError, +} + +def selectExceptionClass(v): + return exceptionClassMapping[v] if v in exceptionClassMapping else Exception + + cdef char * _chars(s): if isinstance(s, unicode): @@ -34,7 +68,7 @@ cdef class CabFile: result = 1 ext.MSPACK_SYS_SELFTEST(result) if result != MSPACK_ERR_OK: - raise Exception("libmspack cannot be used on your system") + raise selectExceptionClass(result)(MSPackError(result), "libmspack cannot be used on your system") self._c_cab_decompressor = ext.mspack_create_cab_decompressor(NULL) if self._c_cab_decompressor is NULL: raise Exception('Cannot create underlying CAB decompressor') @@ -50,7 +84,7 @@ cdef class CabFile: self._c_cabd_cabinet = self._c_cab_decompressor.open(self._c_cab_decompressor, _chars(file_name)) if self._c_cabd_cabinet is NULL: error = self._c_cab_decompressor.last_error(self._c_cab_decompressor) - raise Exception("Cannot open {} file ({})".format(file_name, error)) + raise selectExceptionClass(error)(MSPackError(error), "Cannot open file", file_name) def close(self): if self._c_cab_decompressor is not NULL: @@ -83,7 +117,7 @@ cdef class CabFile: self._must_be_open() if path is not None: if not os_path.isdir(path): - raise Exception("Directory '{}' doesn't exist".format(path)) + raise Exception("Directory doesn't exist", path) destination = os_path.join(path, destination) if isinstance(file_or_info, CabInfo): file_or_info = file_or_info.filename @@ -96,10 +130,9 @@ cdef class CabFile: ret = self._c_cab_decompressor.extract(self._c_cab_decompressor, file_struct, _chars(destination)) if ret == ext.MSPACK_ERR_OK: return True - print ret - raise Exception("Error extracting '{}' ({})".format(file_or_info, ret)) + raise selectExceptionClass(ret)(MSPackError(ret), "Error extracting", file_or_info) file_struct = file_struct.next - raise Exception("File '{}' not in the CAB file".format(file_or_info)) + raise Exception("File not in the CAB file", file_or_info) def _must_be_open(self): if self._c_cab_decompressor is NULL: