diff --git a/.gitignore b/.gitignore index 6e2c5498e..fd4f52364 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *.icloud +Pipfile.lock out *.js diff --git a/.vscode/settings.json b/.vscode/settings.json index d961b0e7e..bf7f61ae1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -288,6 +288,7 @@ "sysconf", "tbitem", "tbody", + "tbtrim", "tcif", "tclass", "tcls", diff --git a/Pipfile b/Pipfile index fdc410b15..55be90a84 100644 --- a/Pipfile +++ b/Pipfile @@ -9,6 +9,7 @@ aenum = "*" setuptools = "*" dictdumper = "*" emoji = "*" +tbtrim = "*" [dev-packages] pcapkit = {editable = true, path = "."} diff --git a/setup.py b/setup.py index 1723c24fe..96c33636c 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ from distutils.core import setup # version string -__version__ = '0.13.0.post2' +__version__ = '0.13.1' # README with open('README.md', encoding='utf-8') as file: @@ -28,7 +28,13 @@ python_requires='>=3.4', include_package_data=True, zip_safe=True, - install_requires=['dictdumper', 'chardet', 'aenum', 'emoji'], + install_requires=[ + 'dictdumper', # for formatted output + 'chardet', # for bytes decode + 'aenum', # for const types + 'emoji', # for CLI display + 'tbtrim', # for refined exceptions + ], extras_require={ 'all': ['dpkt', 'scapy', 'pyshark'], 'DPKT': ['dpkt'], diff --git a/src/__init__.py b/src/__init__.py index 5665b9314..df60b7a5e 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -53,6 +53,11 @@ dump utilities for `pcapkit` implementation """ +# set up sys.excepthook +import os +import tbtrim +tbtrim.set_trim_rule(lambda filename: f'{os.path.sep}pcapkit{os.path.sep}' in filename) + # All Reference import pcapkit.__all__ as all # pylint: disable diff --git a/src/corekit/protochain.py b/src/corekit/protochain.py index f3accdc6b..ff2567f11 100644 --- a/src/corekit/protochain.py +++ b/src/corekit/protochain.py @@ -11,6 +11,7 @@ import re from pcapkit.corekit.infoclass import Info +from pcapkit.utilities.compat import Collection from pcapkit.utilities.exceptions import (IndexNotFound, IntError, ProtocolUnbound) from pcapkit.utilities.validations import int_check, str_check @@ -22,7 +23,7 @@ __all__ = ['ProtoChain'] -class _ProtoList(collections.abc.Collection): +class _ProtoList(Collection): """List of protocol classes for ProtoChain.""" @property def data(self): diff --git a/src/foundation/extraction.py b/src/foundation/extraction.py index 0d1847cfd..56c053f29 100644 --- a/src/foundation/extraction.py +++ b/src/foundation/extraction.py @@ -27,6 +27,7 @@ from pcapkit.corekit.infoclass import Info from pcapkit.protocols.pcap.frame import Frame from pcapkit.protocols.pcap.header import Header +from pcapkit.utilities.compat import pathlib from pcapkit.utilities.exceptions import (CallableError, FileNotFound, FormatError, IterableError, UnsupportedCall, stacklevel) @@ -34,11 +35,6 @@ EngineWarning, FormatWarning, LayerWarning, ProtocolWarning) -try: - import pathlib2 as pathlib -except ImportError: - import pathlib - ############################################################################### # import enum # import multiprocessing diff --git a/src/foundation/traceflow.py b/src/foundation/traceflow.py index 3570aeb7f..62ed8a9f0 100644 --- a/src/foundation/traceflow.py +++ b/src/foundation/traceflow.py @@ -12,15 +12,11 @@ import warnings from pcapkit.corekit.infoclass import Info +from pcapkit.utilities.compat import pathlib from pcapkit.utilities.exceptions import FileExists, stacklevel from pcapkit.utilities.validations import pkt_check from pcapkit.utilities.warnings import FileWarning, FormatWarning -try: - import pathlib2 as pathlib -except ImportError: - import pathlib - ############################################################################### # from dictdumper import JSON, PLIST, XML, JavaScript, Tree # from pcapkit.dumpkit import PCAP, NotImplementedIO diff --git a/src/utilities/__init__.py b/src/utilities/__init__.py index 3a219ba48..fc38b4270 100644 --- a/src/utilities/__init__.py +++ b/src/utilities/__init__.py @@ -7,6 +7,7 @@ user-refined exceptions and validations. """ +from pcapkit.utilities.compat import * from pcapkit.utilities.decorators import * from pcapkit.utilities.exceptions import * from pcapkit.utilities.validations import * diff --git a/src/utilities/compat.py b/src/utilities/compat.py new file mode 100644 index 000000000..d2c6f645a --- /dev/null +++ b/src/utilities/compat.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- + +import builtins +import collections.abc +import sys + +__all__ = [ + 'ModuleNotFoundError', # exceptions + 'Collection', # classes + 'pathlib', # modules +] + +if sys.version_info[:2] < (3, 6): + class ModuleNotFoundError(ImportError): + pass +else: + ModuleNotFoundError = builtins.ModuleNotFoundError + +if sys.version_info[:2] <= (3, 5): + def _check_methods(C, *methods): + mro = C.__mro__ + for method in methods: + for B in mro: + if method in B.__dict__: + if B.__dict__[method] is None: + return NotImplemented + break + else: + return NotImplemented + return True + + class Collection(collections.abc.Sized, collections.abc.Iterable, collections.abc.Container): + + __slots__ = () + + @classmethod + def __subclasshook__(cls, C): + if cls is Collection: + return _check_methods(C, "__len__", "__iter__", "__contains__") + return NotImplemented +else: + Collection = collections.abc.Collection + +if sys.version_info[:2] <= (3, 4): + import pathlib2 as pathlib +else: + import pathlib diff --git a/src/utilities/exceptions.py b/src/utilities/exceptions.py index 721fd991c..3aa210bfc 100644 --- a/src/utilities/exceptions.py +++ b/src/utilities/exceptions.py @@ -11,6 +11,8 @@ import sys import traceback +from pcapkit.utilities.compat import ModuleNotFoundError + __all__ = [ 'BaseError', # Exception 'DigitError', 'IntError', 'RealError', 'ComplexError', # TypeError