Merge pull request #492 from oasis-open/drop-six
Drop 'six' dependency (backwards breaking)pull/1/head
commit
4bccfd26bd
|
@ -10,7 +10,6 @@ known_third_party =
|
||||||
pytz,
|
pytz,
|
||||||
requests,
|
requests,
|
||||||
simplejson,
|
simplejson,
|
||||||
six,
|
|
||||||
sphinx,
|
sphinx,
|
||||||
stix2patterns,
|
stix2patterns,
|
||||||
taxii2client,
|
taxii2client,
|
||||||
|
|
|
@ -23,3 +23,4 @@ repos:
|
||||||
args: ["-c", "--diff"]
|
args: ["-c", "--diff"]
|
||||||
- id: isort
|
- id: isort
|
||||||
name: Sort python imports (fixes files)
|
name: Sort python imports (fixes files)
|
||||||
|
exclude: ^stix2/canonicalization/
|
||||||
|
|
|
@ -21,6 +21,8 @@ Install with `pip <https://pip.pypa.io/en/stable/>`__:
|
||||||
|
|
||||||
$ pip install stix2
|
$ pip install stix2
|
||||||
|
|
||||||
|
Note: The library requires Python 3.6+.
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ import os
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from six import class_types
|
|
||||||
from sphinx.ext.autodoc import ClassDocumenter
|
from sphinx.ext.autodoc import ClassDocumenter
|
||||||
|
|
||||||
from stix2.base import _STIXBase
|
from stix2.base import _STIXBase
|
||||||
|
@ -107,7 +106,7 @@ class STIXPropertyDocumenter(ClassDocumenter):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def can_document_member(cls, member, membername, isattr, parent):
|
def can_document_member(cls, member, membername, isattr, parent):
|
||||||
return isinstance(member, class_types) and \
|
return isinstance(member, type) and \
|
||||||
issubclass(member, _STIXBase) and \
|
issubclass(member, _STIXBase) and \
|
||||||
hasattr(member, '_properties')
|
hasattr(member, '_properties')
|
||||||
|
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -47,11 +47,11 @@ setup(
|
||||||
],
|
],
|
||||||
keywords='stix stix2 json cti cyber threat intelligence',
|
keywords='stix stix2 json cti cyber threat intelligence',
|
||||||
packages=find_packages(exclude=['*.test', '*.test.*']),
|
packages=find_packages(exclude=['*.test', '*.test.*']),
|
||||||
|
python_requires='>=3.6',
|
||||||
install_requires=[
|
install_requires=[
|
||||||
'pytz',
|
'pytz',
|
||||||
'requests',
|
'requests',
|
||||||
'simplejson',
|
'simplejson',
|
||||||
'six>=1.13.0',
|
|
||||||
'stix2-patterns>=1.2.0',
|
'stix2-patterns>=1.2.0',
|
||||||
],
|
],
|
||||||
project_urls={
|
project_urls={
|
||||||
|
|
|
@ -5,7 +5,6 @@ import re
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
import simplejson as json
|
import simplejson as json
|
||||||
import six
|
|
||||||
|
|
||||||
import stix2
|
import stix2
|
||||||
from stix2.canonicalization.Canonicalize import canonicalize
|
from stix2.canonicalization.Canonicalize import canonicalize
|
||||||
|
@ -70,12 +69,9 @@ class _STIXBase(Mapping):
|
||||||
# InvalidValueError... so let those propagate.
|
# InvalidValueError... so let those propagate.
|
||||||
raise
|
raise
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
six.raise_from(
|
raise InvalidValueError(
|
||||||
InvalidValueError(
|
self.__class__, prop_name, reason=str(exc),
|
||||||
self.__class__, prop_name, reason=str(exc),
|
) from exc
|
||||||
),
|
|
||||||
exc,
|
|
||||||
)
|
|
||||||
|
|
||||||
# interproperty constraint methods
|
# interproperty constraint methods
|
||||||
|
|
||||||
|
@ -369,19 +365,8 @@ class _Observable(_STIXBase):
|
||||||
if json_serializable_object:
|
if json_serializable_object:
|
||||||
|
|
||||||
data = canonicalize(json_serializable_object, utf8=False)
|
data = canonicalize(json_serializable_object, utf8=False)
|
||||||
|
uuid_ = uuid.uuid5(SCO_DET_ID_NAMESPACE, data)
|
||||||
# The situation is complicated w.r.t. python 2/3 behavior, so
|
id_ = "{}--{}".format(self._type, str(uuid_))
|
||||||
# I'd rather not rely on particular exceptions being raised to
|
|
||||||
# determine what to do. Better to just check the python version
|
|
||||||
# directly.
|
|
||||||
if six.PY3:
|
|
||||||
uuid_ = uuid.uuid5(SCO_DET_ID_NAMESPACE, data)
|
|
||||||
else:
|
|
||||||
uuid_ = uuid.uuid5(
|
|
||||||
SCO_DET_ID_NAMESPACE, data.encode("utf-8"),
|
|
||||||
)
|
|
||||||
|
|
||||||
id_ = "{}--{}".format(self._type, six.text_type(uuid_))
|
|
||||||
|
|
||||||
return id_
|
return id_
|
||||||
|
|
||||||
|
@ -447,7 +432,7 @@ def _make_json_serializable(value):
|
||||||
for v in value
|
for v in value
|
||||||
]
|
]
|
||||||
|
|
||||||
elif not isinstance(value, (int, float, six.string_types, bool)):
|
elif not isinstance(value, (int, float, str, bool)):
|
||||||
# If a "simple" value which is not already JSON-serializable,
|
# If a "simple" value which is not already JSON-serializable,
|
||||||
# JSON-serialize to a string and use that as our JSON-serializable
|
# JSON-serialize to a string and use that as our JSON-serializable
|
||||||
# value. This applies to our datetime objects currently (timestamp
|
# value. This applies to our datetime objects currently (timestamp
|
||||||
|
|
|
@ -20,12 +20,8 @@
|
||||||
# JCS compatible JSON serializer for Python 3.x #
|
# JCS compatible JSON serializer for Python 3.x #
|
||||||
#################################################
|
#################################################
|
||||||
|
|
||||||
# This file has been modified to be compatible with Python 2.x as well
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
from stix2.canonicalization.NumberToJson import convert2Es6Format
|
from stix2.canonicalization.NumberToJson import convert2Es6Format
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -55,10 +51,10 @@ ESCAPE_DCT = {
|
||||||
}
|
}
|
||||||
for i in range(0x20):
|
for i in range(0x20):
|
||||||
ESCAPE_DCT.setdefault(chr(i), '\\u{0:04x}'.format(i))
|
ESCAPE_DCT.setdefault(chr(i), '\\u{0:04x}'.format(i))
|
||||||
|
#ESCAPE_DCT.setdefault(chr(i), '\\u%04x' % (i,))
|
||||||
|
|
||||||
INFINITY = float('inf')
|
INFINITY = float('inf')
|
||||||
|
|
||||||
|
|
||||||
def py_encode_basestring(s):
|
def py_encode_basestring(s):
|
||||||
"""Return a JSON representation of a Python string
|
"""Return a JSON representation of a Python string
|
||||||
|
|
||||||
|
@ -70,7 +66,6 @@ def py_encode_basestring(s):
|
||||||
|
|
||||||
encode_basestring = (c_encode_basestring or py_encode_basestring)
|
encode_basestring = (c_encode_basestring or py_encode_basestring)
|
||||||
|
|
||||||
|
|
||||||
def py_encode_basestring_ascii(s):
|
def py_encode_basestring_ascii(s):
|
||||||
"""Return an ASCII-only JSON representation of a Python string
|
"""Return an ASCII-only JSON representation of a Python string
|
||||||
|
|
||||||
|
@ -83,6 +78,7 @@ def py_encode_basestring_ascii(s):
|
||||||
n = ord(s)
|
n = ord(s)
|
||||||
if n < 0x10000:
|
if n < 0x10000:
|
||||||
return '\\u{0:04x}'.format(n)
|
return '\\u{0:04x}'.format(n)
|
||||||
|
#return '\\u%04x' % (n,)
|
||||||
else:
|
else:
|
||||||
# surrogate pair
|
# surrogate pair
|
||||||
n -= 0x10000
|
n -= 0x10000
|
||||||
|
@ -96,7 +92,6 @@ encode_basestring_ascii = (
|
||||||
c_encode_basestring_ascii or py_encode_basestring_ascii
|
c_encode_basestring_ascii or py_encode_basestring_ascii
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class JSONEncoder(object):
|
class JSONEncoder(object):
|
||||||
"""Extensible JSON <http://json.org> encoder for Python data structures.
|
"""Extensible JSON <http://json.org> encoder for Python data structures.
|
||||||
|
|
||||||
|
@ -128,11 +123,10 @@ class JSONEncoder(object):
|
||||||
"""
|
"""
|
||||||
item_separator = ', '
|
item_separator = ', '
|
||||||
key_separator = ': '
|
key_separator = ': '
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, skipkeys=False, ensure_ascii=False,
|
self, *, skipkeys=False, ensure_ascii=False,
|
||||||
check_circular=True, allow_nan=True, sort_keys=True,
|
check_circular=True, allow_nan=True, sort_keys=True,
|
||||||
indent=None, separators=(',', ':'), default=None,
|
indent=None, separators=(',', ':'), default=None
|
||||||
):
|
):
|
||||||
"""Constructor for JSONEncoder, with sensible defaults.
|
"""Constructor for JSONEncoder, with sensible defaults.
|
||||||
|
|
||||||
|
@ -277,6 +271,7 @@ class JSONEncoder(object):
|
||||||
|
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
_one_shot and c_make_encoder is not None
|
_one_shot and c_make_encoder is not None
|
||||||
and self.indent is None
|
and self.indent is None
|
||||||
|
@ -294,11 +289,10 @@ class JSONEncoder(object):
|
||||||
)
|
)
|
||||||
return _iterencode(o, 0)
|
return _iterencode(o, 0)
|
||||||
|
|
||||||
|
|
||||||
def _make_iterencode(
|
def _make_iterencode(
|
||||||
markers, _default, _encoder, _indent, _floatstr,
|
markers, _default, _encoder, _indent, _floatstr,
|
||||||
_key_separator, _item_separator, _sort_keys, _skipkeys, _one_shot,
|
_key_separator, _item_separator, _sort_keys, _skipkeys, _one_shot,
|
||||||
# HACK: hand-optimized bytecode; turn globals into locals
|
## HACK: hand-optimized bytecode; turn globals into locals
|
||||||
ValueError=ValueError,
|
ValueError=ValueError,
|
||||||
dict=dict,
|
dict=dict,
|
||||||
float=float,
|
float=float,
|
||||||
|
@ -362,10 +356,7 @@ def _make_iterencode(
|
||||||
chunks = _iterencode_dict(value, _current_indent_level)
|
chunks = _iterencode_dict(value, _current_indent_level)
|
||||||
else:
|
else:
|
||||||
chunks = _iterencode(value, _current_indent_level)
|
chunks = _iterencode(value, _current_indent_level)
|
||||||
# Below line commented-out for python2 compatibility
|
yield from chunks
|
||||||
# yield from chunks
|
|
||||||
for chunk in chunks:
|
|
||||||
yield chunk
|
|
||||||
if newline_indent is not None:
|
if newline_indent is not None:
|
||||||
_current_indent_level -= 1
|
_current_indent_level -= 1
|
||||||
yield '\n' + _indent * _current_indent_level
|
yield '\n' + _indent * _current_indent_level
|
||||||
|
@ -397,8 +388,7 @@ def _make_iterencode(
|
||||||
else:
|
else:
|
||||||
items = dct.items()
|
items = dct.items()
|
||||||
for key, value in items:
|
for key, value in items:
|
||||||
# Replaced isinstance(key, str) with below to enable simultaneous python 2 & 3 compatibility
|
if isinstance(key, str):
|
||||||
if isinstance(key, six.string_types) or isinstance(key, six.binary_type):
|
|
||||||
pass
|
pass
|
||||||
# JavaScript is weakly typed for these, so it makes sense to
|
# JavaScript is weakly typed for these, so it makes sense to
|
||||||
# also allow them. Many encoders seem to do something like this.
|
# also allow them. Many encoders seem to do something like this.
|
||||||
|
@ -445,10 +435,7 @@ def _make_iterencode(
|
||||||
chunks = _iterencode_dict(value, _current_indent_level)
|
chunks = _iterencode_dict(value, _current_indent_level)
|
||||||
else:
|
else:
|
||||||
chunks = _iterencode(value, _current_indent_level)
|
chunks = _iterencode(value, _current_indent_level)
|
||||||
# Below line commented-out for python2 compatibility
|
yield from chunks
|
||||||
# yield from chunks
|
|
||||||
for chunk in chunks:
|
|
||||||
yield chunk
|
|
||||||
if newline_indent is not None:
|
if newline_indent is not None:
|
||||||
_current_indent_level -= 1
|
_current_indent_level -= 1
|
||||||
yield '\n' + _indent * _current_indent_level
|
yield '\n' + _indent * _current_indent_level
|
||||||
|
@ -457,8 +444,7 @@ def _make_iterencode(
|
||||||
del markers[markerid]
|
del markers[markerid]
|
||||||
|
|
||||||
def _iterencode(o, _current_indent_level):
|
def _iterencode(o, _current_indent_level):
|
||||||
# Replaced isinstance(o, str) with below to enable simultaneous python 2 & 3 compatibility
|
if isinstance(o, str):
|
||||||
if isinstance(o, six.string_types) or isinstance(o, six.binary_type):
|
|
||||||
yield _encoder(o)
|
yield _encoder(o)
|
||||||
elif o is None:
|
elif o is None:
|
||||||
yield 'null'
|
yield 'null'
|
||||||
|
@ -473,15 +459,9 @@ def _make_iterencode(
|
||||||
# see comment for int/float in _make_iterencode
|
# see comment for int/float in _make_iterencode
|
||||||
yield convert2Es6Format(o)
|
yield convert2Es6Format(o)
|
||||||
elif isinstance(o, (list, tuple)):
|
elif isinstance(o, (list, tuple)):
|
||||||
# Below line commented-out for python2 compatibility
|
yield from _iterencode_list(o, _current_indent_level)
|
||||||
# yield from _iterencode_list(o, _current_indent_level)
|
|
||||||
for thing in _iterencode_list(o, _current_indent_level):
|
|
||||||
yield thing
|
|
||||||
elif isinstance(o, dict):
|
elif isinstance(o, dict):
|
||||||
# Below line commented-out for python2 compatibility
|
yield from _iterencode_dict(o, _current_indent_level)
|
||||||
# yield from _iterencode_dict(o, _current_indent_level)
|
|
||||||
for thing in _iterencode_dict(o, _current_indent_level):
|
|
||||||
yield thing
|
|
||||||
else:
|
else:
|
||||||
if markers is not None:
|
if markers is not None:
|
||||||
markerid = id(o)
|
markerid = id(o)
|
||||||
|
@ -489,23 +469,18 @@ def _make_iterencode(
|
||||||
raise ValueError("Circular reference detected")
|
raise ValueError("Circular reference detected")
|
||||||
markers[markerid] = o
|
markers[markerid] = o
|
||||||
o = _default(o)
|
o = _default(o)
|
||||||
# Below line commented-out for python2 compatibility
|
yield from _iterencode(o, _current_indent_level)
|
||||||
# yield from _iterencode(o, _current_indent_level)
|
|
||||||
for thing in _iterencode(o, _current_indent_level):
|
|
||||||
yield thing
|
|
||||||
if markers is not None:
|
if markers is not None:
|
||||||
del markers[markerid]
|
del markers[markerid]
|
||||||
return _iterencode
|
return _iterencode
|
||||||
|
|
||||||
|
def canonicalize(obj,utf8=True):
|
||||||
def canonicalize(obj, utf8=True):
|
|
||||||
textVal = JSONEncoder(sort_keys=True).encode(obj)
|
textVal = JSONEncoder(sort_keys=True).encode(obj)
|
||||||
if utf8:
|
if utf8:
|
||||||
return textVal.encode()
|
return textVal.encode()
|
||||||
return textVal
|
return textVal
|
||||||
|
|
||||||
|
def serialize(obj,utf8=True):
|
||||||
def serialize(obj, utf8=True):
|
|
||||||
textVal = JSONEncoder(sort_keys=False).encode(obj)
|
textVal = JSONEncoder(sort_keys=False).encode(obj)
|
||||||
if utf8:
|
if utf8:
|
||||||
return textVal.encode()
|
return textVal.encode()
|
||||||
|
|
|
@ -21,40 +21,50 @@
|
||||||
# Convert a Python double/float into an ES6/V8 compatible string #
|
# Convert a Python double/float into an ES6/V8 compatible string #
|
||||||
##################################################################
|
##################################################################
|
||||||
def convert2Es6Format(value):
|
def convert2Es6Format(value):
|
||||||
# Convert double/float to str using the native Python formatter
|
# Convert double/float to str using the native Python formatter
|
||||||
fvalue = float(value)
|
fvalue = float(value)
|
||||||
|
#
|
||||||
# Zero is a special case. The following line takes "-0" case as well
|
# Zero is a special case. The following line takes "-0" case as well
|
||||||
|
#
|
||||||
if fvalue == 0:
|
if fvalue == 0:
|
||||||
return '0'
|
return '0'
|
||||||
|
#
|
||||||
# The rest of the algorithm works on the textual representation only
|
# The rest of the algorithm works on the textual representation only
|
||||||
|
#
|
||||||
pyDouble = str(fvalue)
|
pyDouble = str(fvalue)
|
||||||
|
#
|
||||||
# The following line catches the "inf" and "nan" values returned by str(fvalue)
|
# The following line catches the "inf" and "nan" values returned by str(fvalue)
|
||||||
|
#
|
||||||
if pyDouble.find('n') >= 0:
|
if pyDouble.find('n') >= 0:
|
||||||
raise ValueError("Invalid JSON number: " + pyDouble)
|
raise ValueError("Invalid JSON number: " + pyDouble)
|
||||||
|
#
|
||||||
# Save sign separately, it doesn't have any role in the algorithm
|
# Save sign separately, it doesn't have any role in the algorithm
|
||||||
|
#
|
||||||
pySign = ''
|
pySign = ''
|
||||||
if pyDouble.find('-') == 0:
|
if pyDouble.find('-') == 0:
|
||||||
pySign = '-'
|
pySign = '-'
|
||||||
pyDouble = pyDouble[1:]
|
pyDouble = pyDouble[1:]
|
||||||
|
#
|
||||||
# Now we should only have valid non-zero values
|
# Now we should only have valid non-zero values
|
||||||
|
#
|
||||||
pyExpStr = ''
|
pyExpStr = ''
|
||||||
pyExpVal = 0
|
pyExpVal = 0
|
||||||
q = pyDouble.find('e')
|
q = pyDouble.find('e')
|
||||||
if q > 0:
|
if q > 0:
|
||||||
# Grab the exponent and remove it from the number
|
#
|
||||||
|
# Grab the exponent and remove it from the number
|
||||||
|
#
|
||||||
pyExpStr = pyDouble[q:]
|
pyExpStr = pyDouble[q:]
|
||||||
if pyExpStr[2:3] == '0':
|
if pyExpStr[2:3] == '0':
|
||||||
# Supress leading zero on exponents
|
#
|
||||||
|
# Supress leading zero on exponents
|
||||||
|
#
|
||||||
pyExpStr = pyExpStr[:2] + pyExpStr[3:]
|
pyExpStr = pyExpStr[:2] + pyExpStr[3:]
|
||||||
pyDouble = pyDouble[0:q]
|
pyDouble = pyDouble[0:q]
|
||||||
pyExpVal = int(pyExpStr[1:])
|
pyExpVal = int(pyExpStr[1:])
|
||||||
|
#
|
||||||
# Split number in pyFirst + pyDot + pyLast
|
# Split number in pyFirst + pyDot + pyLast
|
||||||
|
#
|
||||||
pyFirst = pyDouble
|
pyFirst = pyDouble
|
||||||
pyDot = ''
|
pyDot = ''
|
||||||
pyLast = ''
|
pyLast = ''
|
||||||
|
@ -63,33 +73,40 @@ def convert2Es6Format(value):
|
||||||
pyDot = '.'
|
pyDot = '.'
|
||||||
pyFirst = pyDouble[:q]
|
pyFirst = pyDouble[:q]
|
||||||
pyLast = pyDouble[q + 1:]
|
pyLast = pyDouble[q + 1:]
|
||||||
|
#
|
||||||
# Now the string is split into: pySign + pyFirst + pyDot + pyLast + pyExpStr
|
# Now the string is split into: pySign + pyFirst + pyDot + pyLast + pyExpStr
|
||||||
|
#
|
||||||
if pyLast == '0':
|
if pyLast == '0':
|
||||||
# Always remove trailing .0
|
#
|
||||||
|
# Always remove trailing .0
|
||||||
|
#
|
||||||
pyDot = ''
|
pyDot = ''
|
||||||
pyLast = ''
|
pyLast = ''
|
||||||
|
|
||||||
if pyExpVal > 0 and pyExpVal < 21:
|
if pyExpVal > 0 and pyExpVal < 21:
|
||||||
# Integers are shown as is with up to 21 digits
|
#
|
||||||
|
# Integers are shown as is with up to 21 digits
|
||||||
|
#
|
||||||
pyFirst += pyLast
|
pyFirst += pyLast
|
||||||
pyLast = ''
|
pyLast = ''
|
||||||
pyDot = ''
|
pyDot = ''
|
||||||
pyExpStr = ''
|
pyExpStr = ''
|
||||||
q = pyExpVal - len(pyFirst)
|
q = pyExpVal - len(pyFirst)
|
||||||
while q >= 0:
|
while q >= 0:
|
||||||
q -= 1
|
q -= 1;
|
||||||
pyFirst += '0'
|
pyFirst += '0'
|
||||||
elif pyExpVal < 0 and pyExpVal > -7:
|
elif pyExpVal < 0 and pyExpVal > -7:
|
||||||
# Small numbers are shown as 0.etc with e-6 as lower limit
|
#
|
||||||
|
# Small numbers are shown as 0.etc with e-6 as lower limit
|
||||||
|
#
|
||||||
pyLast = pyFirst + pyLast
|
pyLast = pyFirst + pyLast
|
||||||
pyFirst = '0'
|
pyFirst = '0'
|
||||||
pyDot = '.'
|
pyDot = '.'
|
||||||
pyExpStr = ''
|
pyExpStr = ''
|
||||||
q = pyExpVal
|
q = pyExpVal
|
||||||
while q < -1:
|
while q < -1:
|
||||||
q += 1
|
q += 1;
|
||||||
pyLast = '0' + pyLast
|
pyLast = '0' + pyLast
|
||||||
|
#
|
||||||
# The resulting sub-strings are concatenated
|
# The resulting sub-strings are concatenated
|
||||||
|
#
|
||||||
return pySign + pyFirst + pyDot + pyLast + pyExpStr
|
return pySign + pyFirst + pyDot + pyLast + pyExpStr
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
from .base import _cls_init
|
from .base import _cls_init
|
||||||
from .registration import (
|
from .registration import (
|
||||||
_register_marking, _register_object, _register_observable,
|
_register_marking, _register_object, _register_observable,
|
||||||
|
@ -13,14 +11,11 @@ def _get_properties_dict(properties):
|
||||||
try:
|
try:
|
||||||
return OrderedDict(properties)
|
return OrderedDict(properties)
|
||||||
except TypeError as e:
|
except TypeError as e:
|
||||||
six.raise_from(
|
raise ValueError(
|
||||||
ValueError(
|
"properties must be dict-like, e.g. a list "
|
||||||
"properties must be dict-like, e.g. a list "
|
"containing tuples. For example, "
|
||||||
"containing tuples. For example, "
|
"[('property1', IntegerProperty())]",
|
||||||
"[('property1', IntegerProperty())]",
|
) from e
|
||||||
),
|
|
||||||
e,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _custom_object_builder(cls, type, properties, version, base_class):
|
def _custom_object_builder(cls, type, properties, version, base_class):
|
||||||
|
|
|
@ -15,8 +15,6 @@ Python STIX2 DataStore API.
|
||||||
from abc import ABCMeta, abstractmethod
|
from abc import ABCMeta, abstractmethod
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from six import with_metaclass
|
|
||||||
|
|
||||||
from stix2.datastore.filters import Filter, FilterSet
|
from stix2.datastore.filters import Filter, FilterSet
|
||||||
from stix2.utils import deduplicate
|
from stix2.utils import deduplicate
|
||||||
|
|
||||||
|
@ -219,7 +217,7 @@ class DataStoreMixin(object):
|
||||||
raise AttributeError(msg % self.__class__.__name__)
|
raise AttributeError(msg % self.__class__.__name__)
|
||||||
|
|
||||||
|
|
||||||
class DataSink(with_metaclass(ABCMeta)):
|
class DataSink(metaclass=ABCMeta):
|
||||||
"""An implementer will create a concrete subclass from
|
"""An implementer will create a concrete subclass from
|
||||||
this class for the specific DataSink.
|
this class for the specific DataSink.
|
||||||
|
|
||||||
|
@ -245,7 +243,7 @@ class DataSink(with_metaclass(ABCMeta)):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class DataSource(with_metaclass(ABCMeta)):
|
class DataSource(metaclass=ABCMeta):
|
||||||
"""An implementer will create a concrete subclass from
|
"""An implementer will create a concrete subclass from
|
||||||
this class for the specific DataSource.
|
this class for the specific DataSource.
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,6 @@ import os
|
||||||
import re
|
import re
|
||||||
import stat
|
import stat
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
from stix2 import v20, v21
|
from stix2 import v20, v21
|
||||||
from stix2.base import _STIXBase
|
from stix2.base import _STIXBase
|
||||||
from stix2.datastore import (
|
from stix2.datastore import (
|
||||||
|
@ -116,7 +114,7 @@ def _update_allow(allow_set, value):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
adding_seq = hasattr(value, "__iter__") and \
|
adding_seq = hasattr(value, "__iter__") and \
|
||||||
not isinstance(value, six.string_types)
|
not isinstance(value, str)
|
||||||
|
|
||||||
if allow_set is None:
|
if allow_set is None:
|
||||||
allow_set = set()
|
allow_set = set()
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
import collections
|
import collections
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
import stix2.utils
|
import stix2.utils
|
||||||
|
|
||||||
"""Supported filter operations"""
|
"""Supported filter operations"""
|
||||||
|
@ -12,8 +10,7 @@ FILTER_OPS = ['=', '!=', 'in', '>', '<', '>=', '<=', 'contains']
|
||||||
|
|
||||||
"""Supported filter value types"""
|
"""Supported filter value types"""
|
||||||
FILTER_VALUE_TYPES = (
|
FILTER_VALUE_TYPES = (
|
||||||
bool, dict, float, int, list, tuple, six.string_types,
|
bool, dict, float, int, list, tuple, str, datetime,
|
||||||
datetime,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -84,7 +81,7 @@ class Filter(collections.namedtuple('Filter', ['property', 'op', 'value'])):
|
||||||
# If filtering on a timestamp property and the filter value is a string,
|
# If filtering on a timestamp property and the filter value is a string,
|
||||||
# try to convert the filter value to a datetime instance.
|
# try to convert the filter value to a datetime instance.
|
||||||
if isinstance(stix_obj_property, datetime) and \
|
if isinstance(stix_obj_property, datetime) and \
|
||||||
isinstance(self.value, six.string_types):
|
isinstance(self.value, str):
|
||||||
filter_value = stix2.utils.parse_into_datetime(self.value)
|
filter_value = stix2.utils.parse_into_datetime(self.value)
|
||||||
else:
|
else:
|
||||||
filter_value = self.value
|
filter_value = self.value
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
from stix2 import exceptions, utils
|
from stix2 import exceptions, utils
|
||||||
|
|
||||||
|
|
||||||
|
@ -129,7 +127,7 @@ def compress_markings(granular_markings):
|
||||||
{'marking_ref': item, 'selectors': sorted(selectors)}
|
{'marking_ref': item, 'selectors': sorted(selectors)}
|
||||||
if utils.is_marking(item) else
|
if utils.is_marking(item) else
|
||||||
{'lang': item, 'selectors': sorted(selectors)}
|
{'lang': item, 'selectors': sorted(selectors)}
|
||||||
for item, selectors in six.iteritems(map_)
|
for item, selectors in map_.items()
|
||||||
]
|
]
|
||||||
|
|
||||||
return compressed
|
return compressed
|
||||||
|
@ -230,7 +228,7 @@ def iterpath(obj, path=None):
|
||||||
if path is None:
|
if path is None:
|
||||||
path = []
|
path = []
|
||||||
|
|
||||||
for varname, varobj in iter(sorted(six.iteritems(obj))):
|
for varname, varobj in iter(sorted(obj.items())):
|
||||||
path.append(varname)
|
path.append(varname)
|
||||||
yield (path, varobj)
|
yield (path, varobj)
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
import importlib
|
import importlib
|
||||||
import inspect
|
import inspect
|
||||||
|
|
||||||
from six import text_type
|
|
||||||
from stix2patterns.exceptions import ParseException
|
from stix2patterns.exceptions import ParseException
|
||||||
from stix2patterns.grammars.STIXPatternParser import TerminalNode
|
from stix2patterns.grammars.STIXPatternParser import TerminalNode
|
||||||
from stix2patterns.v20.grammars.STIXPatternParser import \
|
from stix2patterns.v20.grammars.STIXPatternParser import \
|
||||||
|
@ -263,7 +262,7 @@ class STIXPatternVisitorForSTIX2():
|
||||||
property_path.append(
|
property_path.append(
|
||||||
self.instantiate(
|
self.instantiate(
|
||||||
"ListObjectPathComponent",
|
"ListObjectPathComponent",
|
||||||
current.property_name if isinstance(current, BasicObjectPathComponent) else text_type(current),
|
current.property_name if isinstance(current, BasicObjectPathComponent) else str(current),
|
||||||
next.value,
|
next.value,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -286,7 +285,7 @@ class STIXPatternVisitorForSTIX2():
|
||||||
if isinstance(first_component, TerminalNode):
|
if isinstance(first_component, TerminalNode):
|
||||||
step = first_component.getText()
|
step = first_component.getText()
|
||||||
else:
|
else:
|
||||||
step = text_type(first_component)
|
step = str(first_component)
|
||||||
# if step.endswith("_ref"):
|
# if step.endswith("_ref"):
|
||||||
# return stix2.ReferenceObjectPathComponent(step)
|
# return stix2.ReferenceObjectPathComponent(step)
|
||||||
# else:
|
# else:
|
||||||
|
|
|
@ -5,8 +5,6 @@ import binascii
|
||||||
import datetime
|
import datetime
|
||||||
import re
|
import re
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
from .utils import parse_into_datetime
|
from .utils import parse_into_datetime
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,7 +13,7 @@ def escape_quotes_and_backslashes(s):
|
||||||
|
|
||||||
|
|
||||||
def quote_if_needed(x):
|
def quote_if_needed(x):
|
||||||
if isinstance(x, six.string_types):
|
if isinstance(x, str):
|
||||||
if x.find("-") != -1:
|
if x.find("-") != -1:
|
||||||
if not x.startswith("'"):
|
if not x.startswith("'"):
|
||||||
return "'" + x + "'"
|
return "'" + x + "'"
|
||||||
|
|
|
@ -7,8 +7,6 @@ import inspect
|
||||||
import re
|
import re
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from six import string_types, text_type
|
|
||||||
|
|
||||||
from .base import _STIXBase
|
from .base import _STIXBase
|
||||||
from .exceptions import (
|
from .exceptions import (
|
||||||
CustomContentError, DictionaryKeyError, MissingPropertiesError,
|
CustomContentError, DictionaryKeyError, MissingPropertiesError,
|
||||||
|
@ -227,7 +225,7 @@ class ListProperty(Property):
|
||||||
except TypeError:
|
except TypeError:
|
||||||
raise ValueError("must be an iterable.")
|
raise ValueError("must be an iterable.")
|
||||||
|
|
||||||
if isinstance(value, (_STIXBase, string_types)):
|
if isinstance(value, (_STIXBase, str)):
|
||||||
value = [value]
|
value = [value]
|
||||||
|
|
||||||
if isinstance(self.contained, Property):
|
if isinstance(self.contained, Property):
|
||||||
|
@ -268,8 +266,8 @@ class StringProperty(Property):
|
||||||
super(StringProperty, self).__init__(**kwargs)
|
super(StringProperty, self).__init__(**kwargs)
|
||||||
|
|
||||||
def clean(self, value):
|
def clean(self, value):
|
||||||
if not isinstance(value, string_types):
|
if not isinstance(value, str):
|
||||||
return text_type(value)
|
return str(value)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -128,18 +128,17 @@ def test_filter_value_type_check():
|
||||||
|
|
||||||
with pytest.raises(TypeError) as excinfo:
|
with pytest.raises(TypeError) as excinfo:
|
||||||
Filter('created', '=', object())
|
Filter('created', '=', object())
|
||||||
# On Python 2, the type of object() is `<type 'object'>` On Python 3, it's `<class 'object'>`.
|
assert "'<class 'object'>'" in str(excinfo.value)
|
||||||
assert any([s in str(excinfo.value) for s in ["<type 'object'>", "'<class 'object'>'"]])
|
|
||||||
assert "is not supported. The type must be a Python immutable type or dictionary" in str(excinfo.value)
|
assert "is not supported. The type must be a Python immutable type or dictionary" in str(excinfo.value)
|
||||||
|
|
||||||
with pytest.raises(TypeError) as excinfo:
|
with pytest.raises(TypeError) as excinfo:
|
||||||
Filter("type", "=", complex(2, -1))
|
Filter("type", "=", complex(2, -1))
|
||||||
assert any([s in str(excinfo.value) for s in ["<type 'complex'>", "'<class 'complex'>'"]])
|
assert "'<class 'complex'>'" in str(excinfo.value)
|
||||||
assert "is not supported. The type must be a Python immutable type or dictionary" in str(excinfo.value)
|
assert "is not supported. The type must be a Python immutable type or dictionary" in str(excinfo.value)
|
||||||
|
|
||||||
with pytest.raises(TypeError) as excinfo:
|
with pytest.raises(TypeError) as excinfo:
|
||||||
Filter("type", "=", set([16, 23]))
|
Filter("type", "=", set([16, 23]))
|
||||||
assert any([s in str(excinfo.value) for s in ["<type 'set'>", "'<class 'set'>'"]])
|
assert "'<class 'set'>'" in str(excinfo.value)
|
||||||
assert "is not supported. The type must be a Python immutable type or dictionary" in str(excinfo.value)
|
assert "is not supported. The type must be a Python immutable type or dictionary" in str(excinfo.value)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ import json
|
||||||
from medallion.filters.basic_filter import BasicFilter
|
from medallion.filters.basic_filter import BasicFilter
|
||||||
import pytest
|
import pytest
|
||||||
from requests.models import Response
|
from requests.models import Response
|
||||||
import six
|
|
||||||
from taxii2client.common import _filter_kwargs_to_query_params
|
from taxii2client.common import _filter_kwargs_to_query_params
|
||||||
from taxii2client.v20 import Collection
|
from taxii2client.v20 import Collection
|
||||||
|
|
||||||
|
@ -27,7 +26,7 @@ class MockTAXIICollectionEndpoint(Collection):
|
||||||
|
|
||||||
def add_objects(self, bundle):
|
def add_objects(self, bundle):
|
||||||
self._verify_can_write()
|
self._verify_can_write()
|
||||||
if isinstance(bundle, six.string_types):
|
if isinstance(bundle, str):
|
||||||
bundle = json.loads(bundle)
|
bundle = json.loads(bundle)
|
||||||
for object in bundle.get("objects", []):
|
for object in bundle.get("objects", []):
|
||||||
self.objects.append(object)
|
self.objects.append(object)
|
||||||
|
|
|
@ -146,18 +146,17 @@ def test_filter_value_type_check():
|
||||||
|
|
||||||
with pytest.raises(TypeError) as excinfo:
|
with pytest.raises(TypeError) as excinfo:
|
||||||
Filter('created', '=', object())
|
Filter('created', '=', object())
|
||||||
# On Python 2, the type of object() is `<type 'object'>` On Python 3, it's `<class 'object'>`.
|
assert "'<class 'object'>'" in str(excinfo.value)
|
||||||
assert any([s in str(excinfo.value) for s in ["<type 'object'>", "'<class 'object'>'"]])
|
|
||||||
assert "is not supported. The type must be a Python immutable type or dictionary" in str(excinfo.value)
|
assert "is not supported. The type must be a Python immutable type or dictionary" in str(excinfo.value)
|
||||||
|
|
||||||
with pytest.raises(TypeError) as excinfo:
|
with pytest.raises(TypeError) as excinfo:
|
||||||
Filter("type", "=", complex(2, -1))
|
Filter("type", "=", complex(2, -1))
|
||||||
assert any([s in str(excinfo.value) for s in ["<type 'complex'>", "'<class 'complex'>'"]])
|
assert "'<class 'complex'>'" in str(excinfo.value)
|
||||||
assert "is not supported. The type must be a Python immutable type or dictionary" in str(excinfo.value)
|
assert "is not supported. The type must be a Python immutable type or dictionary" in str(excinfo.value)
|
||||||
|
|
||||||
with pytest.raises(TypeError) as excinfo:
|
with pytest.raises(TypeError) as excinfo:
|
||||||
Filter("type", "=", set([16, 23]))
|
Filter("type", "=", set([16, 23]))
|
||||||
assert any([s in str(excinfo.value) for s in ["<type 'set'>", "'<class 'set'>'"]])
|
assert "'<class 'set'>'" in str(excinfo.value)
|
||||||
assert "is not supported. The type must be a Python immutable type or dictionary" in str(excinfo.value)
|
assert "is not supported. The type must be a Python immutable type or dictionary" in str(excinfo.value)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ import json
|
||||||
from medallion.filters.basic_filter import BasicFilter
|
from medallion.filters.basic_filter import BasicFilter
|
||||||
import pytest
|
import pytest
|
||||||
from requests.models import Response
|
from requests.models import Response
|
||||||
import six
|
|
||||||
from taxii2client.common import _filter_kwargs_to_query_params
|
from taxii2client.common import _filter_kwargs_to_query_params
|
||||||
from taxii2client.v21 import Collection
|
from taxii2client.v21 import Collection
|
||||||
|
|
||||||
|
@ -27,7 +26,7 @@ class MockTAXIICollectionEndpoint(Collection):
|
||||||
|
|
||||||
def add_objects(self, bundle):
|
def add_objects(self, bundle):
|
||||||
self._verify_can_write()
|
self._verify_can_write()
|
||||||
if isinstance(bundle, six.string_types):
|
if isinstance(bundle, str):
|
||||||
bundle = json.loads(bundle)
|
bundle = json.loads(bundle)
|
||||||
for object in bundle.get("objects", []):
|
for object in bundle.get("objects", []):
|
||||||
self.objects.append(object)
|
self.objects.append(object)
|
||||||
|
|
|
@ -3,7 +3,6 @@ import datetime
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import six
|
|
||||||
|
|
||||||
import stix2.base
|
import stix2.base
|
||||||
import stix2.canonicalization.Canonicalize
|
import stix2.canonicalization.Canonicalize
|
||||||
|
@ -31,12 +30,7 @@ def _make_uuid5(name):
|
||||||
"""
|
"""
|
||||||
Make a STIX 2.1+ compliant UUIDv5 from a "name".
|
Make a STIX 2.1+ compliant UUIDv5 from a "name".
|
||||||
"""
|
"""
|
||||||
if six.PY3:
|
uuid_ = uuid.uuid5(SCO_DET_ID_NAMESPACE, name)
|
||||||
uuid_ = uuid.uuid5(SCO_DET_ID_NAMESPACE, name)
|
|
||||||
else:
|
|
||||||
uuid_ = uuid.uuid5(
|
|
||||||
SCO_DET_ID_NAMESPACE, name.encode("utf-8"),
|
|
||||||
)
|
|
||||||
|
|
||||||
return uuid_
|
return uuid_
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ import json
|
||||||
import re
|
import re
|
||||||
|
|
||||||
import pytz
|
import pytz
|
||||||
import six
|
|
||||||
|
|
||||||
import stix2.registry as mappings
|
import stix2.registry as mappings
|
||||||
import stix2.version
|
import stix2.version
|
||||||
|
@ -70,7 +69,7 @@ def _to_enum(value, enum_type, enum_default=None):
|
||||||
if not isinstance(value, enum_type):
|
if not isinstance(value, enum_type):
|
||||||
if value is None and enum_default is not None:
|
if value is None and enum_default is not None:
|
||||||
value = enum_default
|
value = enum_default
|
||||||
elif isinstance(value, six.string_types):
|
elif isinstance(value, str):
|
||||||
value = enum_type[value.upper()]
|
value = enum_type[value.upper()]
|
||||||
else:
|
else:
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
from ..custom import _custom_marking_builder
|
from ..custom import _custom_marking_builder
|
||||||
from ..markings import _MarkingsMixin
|
from ..markings import _MarkingsMixin
|
||||||
from ..markings.utils import check_tlp_marking
|
from ..markings.utils import check_tlp_marking
|
||||||
|
@ -21,7 +19,7 @@ def _should_set_millisecond(cr, marking_type):
|
||||||
if marking_type == TLPMarking:
|
if marking_type == TLPMarking:
|
||||||
return True
|
return True
|
||||||
# otherwise, precision is kept from how it was given
|
# otherwise, precision is kept from how it was given
|
||||||
if isinstance(cr, six.string_types):
|
if isinstance(cr, str):
|
||||||
if '.' in cr:
|
if '.' in cr:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
import itertools
|
import itertools
|
||||||
|
from urllib.parse import quote_plus
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from six.moves.urllib.parse import quote_plus
|
|
||||||
from stix2patterns.validator import run_validator
|
from stix2patterns.validator import run_validator
|
||||||
|
|
||||||
from ..custom import _custom_object_builder
|
from ..custom import _custom_object_builder
|
||||||
|
|
Loading…
Reference in New Issue