mirror of
https://github.com/SELinuxProject/setools
synced 2025-03-11 07:18:15 +00:00
setools.*: standardize queries to None defaults instead of empty strings.
Clearer intent and nicer for logging output. Removes unnecessary type conversions.
This commit is contained in:
parent
de716ba6a5
commit
f216d7cf24
@ -26,7 +26,7 @@ class BoolQuery(compquery.ComponentQuery):
|
|||||||
"""Query SELinux policy Booleans."""
|
"""Query SELinux policy Booleans."""
|
||||||
|
|
||||||
def __init__(self, policy,
|
def __init__(self, policy,
|
||||||
name="", name_regex=False,
|
name=None, name_regex=False,
|
||||||
default=False, match_default=False):
|
default=False, match_default=False):
|
||||||
"""
|
"""
|
||||||
Parameter:
|
Parameter:
|
||||||
|
@ -27,8 +27,8 @@ class CategoryQuery(mixins.MatchAlias, compquery.ComponentQuery):
|
|||||||
"""Query MLS Categories"""
|
"""Query MLS Categories"""
|
||||||
|
|
||||||
def __init__(self, policy,
|
def __init__(self, policy,
|
||||||
name="", name_regex=False,
|
name=None, name_regex=False,
|
||||||
alias="", alias_regex=False):
|
alias=None, alias_regex=False):
|
||||||
"""
|
"""
|
||||||
Parameters:
|
Parameters:
|
||||||
name The name of the category to match.
|
name The name of the category to match.
|
||||||
|
@ -26,8 +26,8 @@ class CommonQuery(compquery.ComponentQuery):
|
|||||||
"""Query common permission sets."""
|
"""Query common permission sets."""
|
||||||
|
|
||||||
def __init__(self, policy,
|
def __init__(self, policy,
|
||||||
name="", name_regex=False,
|
name=None, name_regex=False,
|
||||||
perms=set(), perms_equal=False, perms_regex=False):
|
perms=None, perms_equal=False, perms_regex=False):
|
||||||
"""
|
"""
|
||||||
Parameters:
|
Parameters:
|
||||||
name The name of the common to match.
|
name The name of the common to match.
|
||||||
|
@ -41,7 +41,7 @@ class ComponentQuery(query.PolicyQuery):
|
|||||||
NameError Invalid keyword option.
|
NameError Invalid keyword option.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.name = str(name)
|
self.name = name
|
||||||
|
|
||||||
for k in list(opts.keys()):
|
for k in list(opts.keys()):
|
||||||
if k == "regex":
|
if k == "regex":
|
||||||
|
@ -28,12 +28,12 @@ class ConstraintQuery(mixins.MatchObjClass, mixins.MatchPermission, PolicyQuery)
|
|||||||
"""Query constraint rules, (mls)constrain/(mls)validatetrans."""
|
"""Query constraint rules, (mls)constrain/(mls)validatetrans."""
|
||||||
|
|
||||||
def __init__(self, policy,
|
def __init__(self, policy,
|
||||||
ruletype=[],
|
ruletype=None,
|
||||||
tclass="", tclass_regex=False,
|
tclass=None, tclass_regex=False,
|
||||||
perms=set(), perms_equal=False,
|
perms=None, perms_equal=False,
|
||||||
role="", role_regex=False, role_indirect=True,
|
role=None, role_regex=False, role_indirect=True,
|
||||||
type_="", type_regex=False, type_indirect=True,
|
type_=None, type_regex=False, type_indirect=True,
|
||||||
user="", user_regex=False):
|
user=None, user_regex=False):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Parameter:
|
Parameter:
|
||||||
|
@ -98,7 +98,7 @@ class ContextQuery(query.PolicyQuery):
|
|||||||
NameError Invalid keyword option.
|
NameError Invalid keyword option.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.user = str(user)
|
self.user = user
|
||||||
|
|
||||||
for k in list(opts.keys()):
|
for k in list(opts.keys()):
|
||||||
if k == "regex":
|
if k == "regex":
|
||||||
@ -125,7 +125,7 @@ class ContextQuery(query.PolicyQuery):
|
|||||||
NameError Invalid keyword option.
|
NameError Invalid keyword option.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.role = str(role)
|
self.role = role
|
||||||
|
|
||||||
for k in list(opts.keys()):
|
for k in list(opts.keys()):
|
||||||
if k == "regex":
|
if k == "regex":
|
||||||
@ -152,7 +152,7 @@ class ContextQuery(query.PolicyQuery):
|
|||||||
NameError Invalid keyword option.
|
NameError Invalid keyword option.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.type_ = str(type_)
|
self.type_ = type_
|
||||||
|
|
||||||
for k in list(opts.keys()):
|
for k in list(opts.keys()):
|
||||||
if k == "regex":
|
if k == "regex":
|
||||||
|
@ -27,12 +27,12 @@ class FSUseQuery(contextquery.ContextQuery):
|
|||||||
"""Query fs_use_* statements."""
|
"""Query fs_use_* statements."""
|
||||||
|
|
||||||
def __init__(self, policy,
|
def __init__(self, policy,
|
||||||
ruletype=[],
|
ruletype=None,
|
||||||
fs="", fs_regex=False,
|
fs=None, fs_regex=False,
|
||||||
user="", user_regex=False,
|
user=None, user_regex=False,
|
||||||
role="", role_regex=False,
|
role=None, role_regex=False,
|
||||||
type_="", type_regex=False,
|
type_=None, type_regex=False,
|
||||||
range_="", range_overlap=False, range_subset=False,
|
range_=None, range_overlap=False, range_subset=False,
|
||||||
range_superset=False, range_proper=False):
|
range_superset=False, range_proper=False):
|
||||||
"""
|
"""
|
||||||
Parameters:
|
Parameters:
|
||||||
@ -124,7 +124,7 @@ class FSUseQuery(contextquery.ContextQuery):
|
|||||||
NameError Invalid keyword option.
|
NameError Invalid keyword option.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.fs = str(fs)
|
self.fs = fs
|
||||||
|
|
||||||
for k in list(opts.keys()):
|
for k in list(opts.keys()):
|
||||||
if k == "regex":
|
if k == "regex":
|
||||||
|
@ -27,13 +27,13 @@ class GenfsconQuery(contextquery.ContextQuery):
|
|||||||
"""Query genfscon statements."""
|
"""Query genfscon statements."""
|
||||||
|
|
||||||
def __init__(self, policy,
|
def __init__(self, policy,
|
||||||
fs="", fs_regex=False,
|
fs=None, fs_regex=False,
|
||||||
path="", path_regex=False,
|
path=None, path_regex=False,
|
||||||
filetype=0,
|
filetype=None,
|
||||||
user="", user_regex=False,
|
user=None, user_regex=False,
|
||||||
role="", role_regex=False,
|
role=None, role_regex=False,
|
||||||
type_="", type_regex=False,
|
type_=None, type_regex=False,
|
||||||
range_="", range_overlap=False, range_subset=False,
|
range_=None, range_overlap=False, range_subset=False,
|
||||||
range_superset=False, range_proper=False):
|
range_superset=False, range_proper=False):
|
||||||
"""
|
"""
|
||||||
Parameters:
|
Parameters:
|
||||||
@ -124,7 +124,7 @@ class GenfsconQuery(contextquery.ContextQuery):
|
|||||||
NameError Invalid keyword option.
|
NameError Invalid keyword option.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.fs = str(fs)
|
self.fs = fs
|
||||||
|
|
||||||
for k in list(opts.keys()):
|
for k in list(opts.keys()):
|
||||||
if k == "regex":
|
if k == "regex":
|
||||||
@ -161,7 +161,7 @@ class GenfsconQuery(contextquery.ContextQuery):
|
|||||||
NameError Invalid keyword option.
|
NameError Invalid keyword option.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.path = str(path)
|
self.path = path
|
||||||
|
|
||||||
for k in list(opts.keys()):
|
for k in list(opts.keys()):
|
||||||
if k == "regex":
|
if k == "regex":
|
||||||
|
@ -25,11 +25,11 @@ class InitialSIDQuery(compquery.ComponentQuery, contextquery.ContextQuery):
|
|||||||
"""Initial SID (context) query."""
|
"""Initial SID (context) query."""
|
||||||
|
|
||||||
def __init__(self, policy,
|
def __init__(self, policy,
|
||||||
name="", name_regex=False,
|
name=None, name_regex=False,
|
||||||
user="", user_regex=False,
|
user=None, user_regex=False,
|
||||||
role="", role_regex=False,
|
role=None, role_regex=False,
|
||||||
type_="", type_regex=False,
|
type_=None, type_regex=False,
|
||||||
range_="", range_overlap=False, range_subset=False,
|
range_=None, range_overlap=False, range_subset=False,
|
||||||
range_superset=False, range_proper=False):
|
range_superset=False, range_proper=False):
|
||||||
"""
|
"""
|
||||||
Parameters:
|
Parameters:
|
||||||
|
@ -111,7 +111,7 @@ class MatchPermission(object):
|
|||||||
|
|
||||||
def _match_perms(self, obj):
|
def _match_perms(self, obj):
|
||||||
"""Match the object to the permission criteria."""
|
"""Match the object to the permission criteria."""
|
||||||
return self._match_set(obj, self.perms, self.perms_equal)
|
return self._match_set(obj, self.perms_cmp, self.perms_equal)
|
||||||
|
|
||||||
def set_perms(self, perms, **opts):
|
def set_perms(self, perms, **opts):
|
||||||
"""
|
"""
|
||||||
@ -130,13 +130,15 @@ class MatchPermission(object):
|
|||||||
NameError Invalid permission set keyword option.
|
NameError Invalid permission set keyword option.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if isinstance(perms, str):
|
self.perms = perms
|
||||||
self.perms = perms
|
|
||||||
else:
|
|
||||||
self.perms = set(perms)
|
|
||||||
|
|
||||||
for k in list(opts.keys()):
|
for k in list(opts.keys()):
|
||||||
if k == "equal":
|
if k == "equal":
|
||||||
self.perms_equal = opts[k]
|
self.perms_equal = opts[k]
|
||||||
else:
|
else:
|
||||||
raise NameError("Invalid permission set option: {0}".format(k))
|
raise NameError("Invalid permission set option: {0}".format(k))
|
||||||
|
|
||||||
|
if not self.perms:
|
||||||
|
self.perms_cmp = None
|
||||||
|
else:
|
||||||
|
self.perms_cmp = set(self.perms)
|
||||||
|
@ -24,11 +24,11 @@ class MLSRuleQuery(rulequery.RuleQuery):
|
|||||||
"""Query MLS rules."""
|
"""Query MLS rules."""
|
||||||
|
|
||||||
def __init__(self, policy,
|
def __init__(self, policy,
|
||||||
ruletype=[],
|
ruletype=None,
|
||||||
source="", source_regex=False,
|
source=None, source_regex=False,
|
||||||
target="", target_regex=False,
|
target=None, target_regex=False,
|
||||||
tclass="", tclass_regex=False,
|
tclass=None, tclass_regex=False,
|
||||||
default="", default_overlap=False, default_subset=False,
|
default=None, default_overlap=False, default_subset=False,
|
||||||
default_superset=False, default_proper=False):
|
default_superset=False, default_proper=False):
|
||||||
"""
|
"""
|
||||||
Parameters:
|
Parameters:
|
||||||
|
@ -25,11 +25,11 @@ class NetifconQuery(compquery.ComponentQuery, contextquery.ContextQuery):
|
|||||||
"""Network interface context query."""
|
"""Network interface context query."""
|
||||||
|
|
||||||
def __init__(self, policy,
|
def __init__(self, policy,
|
||||||
name="", name_regex=False,
|
name=None, name_regex=False,
|
||||||
user="", user_regex=False,
|
user=None, user_regex=False,
|
||||||
role="", role_regex=False,
|
role=None, role_regex=False,
|
||||||
type_="", type_regex=False,
|
type_=None, type_regex=False,
|
||||||
range_="", range_overlap=False, range_subset=False,
|
range_=None, range_overlap=False, range_subset=False,
|
||||||
range_superset=False, range_proper=False):
|
range_superset=False, range_proper=False):
|
||||||
"""
|
"""
|
||||||
Parameters:
|
Parameters:
|
||||||
|
@ -33,12 +33,12 @@ class NodeconQuery(contextquery.ContextQuery):
|
|||||||
"""Query nodecon statements."""
|
"""Query nodecon statements."""
|
||||||
|
|
||||||
def __init__(self, policy,
|
def __init__(self, policy,
|
||||||
net="", net_overlap=False,
|
net=None, net_overlap=False,
|
||||||
version=0,
|
version=None,
|
||||||
user="", user_regex=False,
|
user=None, user_regex=False,
|
||||||
role="", role_regex=False,
|
role=None, role_regex=False,
|
||||||
type_="", type_regex=False,
|
type_=None, type_regex=False,
|
||||||
range_="", range_overlap=False, range_subset=False,
|
range_=None, range_overlap=False, range_subset=False,
|
||||||
range_superset=False, range_proper=False):
|
range_superset=False, range_proper=False):
|
||||||
"""
|
"""
|
||||||
Parameters:
|
Parameters:
|
||||||
|
@ -27,9 +27,9 @@ class ObjClassQuery(compquery.ComponentQuery):
|
|||||||
"""Query object classes."""
|
"""Query object classes."""
|
||||||
|
|
||||||
def __init__(self, policy,
|
def __init__(self, policy,
|
||||||
name="", name_regex=False,
|
name=None, name_regex=False,
|
||||||
common="", common_regex=False,
|
common=None, common_regex=False,
|
||||||
perms=set(), perms_equal=False, perms_regex=False,
|
perms=None, perms_equal=False, perms_regex=False,
|
||||||
perms_indirect=True):
|
perms_indirect=True):
|
||||||
"""
|
"""
|
||||||
Parameters:
|
Parameters:
|
||||||
@ -105,7 +105,7 @@ class ObjClassQuery(compquery.ComponentQuery):
|
|||||||
NameError Invalid keyword option.
|
NameError Invalid keyword option.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.common = str(common)
|
self.common = common
|
||||||
|
|
||||||
for k in list(opts.keys()):
|
for k in list(opts.keys()):
|
||||||
if k == "regex":
|
if k == "regex":
|
||||||
|
@ -26,7 +26,7 @@ class PolCapQuery(compquery.ComponentQuery):
|
|||||||
"""Query SELinux policy capabilities"""
|
"""Query SELinux policy capabilities"""
|
||||||
|
|
||||||
def __init__(self, policy,
|
def __init__(self, policy,
|
||||||
name="", name_regex=False):
|
name=None, name_regex=False):
|
||||||
"""
|
"""
|
||||||
Parameters:
|
Parameters:
|
||||||
name The name of the policy capability to match.
|
name The name of the policy capability to match.
|
||||||
|
@ -26,13 +26,13 @@ class PortconQuery(contextquery.ContextQuery):
|
|||||||
"""Port context query."""
|
"""Port context query."""
|
||||||
|
|
||||||
def __init__(self, policy,
|
def __init__(self, policy,
|
||||||
protocol=0,
|
protocol=None,
|
||||||
ports=(0, 0), ports_subset=False, ports_overlap=False,
|
ports=(None, None), ports_subset=False, ports_overlap=False,
|
||||||
ports_superset=False, ports_proper=False,
|
ports_superset=False, ports_proper=False,
|
||||||
user="", user_regex=False,
|
user=None, user_regex=False,
|
||||||
role="", role_regex=False,
|
role=None, role_regex=False,
|
||||||
type_="", type_regex=False,
|
type_=None, type_regex=False,
|
||||||
range_="", range_overlap=False, range_subset=False,
|
range_=None, range_overlap=False, range_subset=False,
|
||||||
range_superset=False, range_proper=False):
|
range_superset=False, range_proper=False):
|
||||||
"""
|
"""
|
||||||
Parameters:
|
Parameters:
|
||||||
@ -92,10 +92,10 @@ class PortconQuery(contextquery.ContextQuery):
|
|||||||
|
|
||||||
for p in self.policy.portcons():
|
for p in self.policy.portcons():
|
||||||
|
|
||||||
if any(self.ports):
|
if all(self.ports):
|
||||||
if not self._match_range(
|
if not self._match_range(
|
||||||
p.ports,
|
p.ports,
|
||||||
self.ports,
|
self.ports_cmp,
|
||||||
self.subset,
|
self.subset,
|
||||||
self.overlap,
|
self.overlap,
|
||||||
self.superset,
|
self.superset,
|
||||||
@ -141,16 +141,7 @@ class PortconQuery(contextquery.ContextQuery):
|
|||||||
No effect if not using set operations.
|
No effect if not using set operations.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
pending_ports = (int(ports[0]), int(ports[1]))
|
self.ports = ports
|
||||||
|
|
||||||
if (pending_ports[0] < 0 or pending_ports[1] < 0):
|
|
||||||
raise ValueError("Port numbers must be positive: {0[0]}-{0[1]}".format(ports))
|
|
||||||
|
|
||||||
if (pending_ports[0] > pending_ports[1]):
|
|
||||||
raise ValueError(
|
|
||||||
"The low port must be smaller than the high port: {0[0]}-{0[1]}".format(ports))
|
|
||||||
|
|
||||||
self.ports = pending_ports
|
|
||||||
|
|
||||||
for k in list(opts.keys()):
|
for k in list(opts.keys()):
|
||||||
if k == "subset":
|
if k == "subset":
|
||||||
@ -164,6 +155,18 @@ class PortconQuery(contextquery.ContextQuery):
|
|||||||
else:
|
else:
|
||||||
raise NameError("Invalid name option: {0}".format(k))
|
raise NameError("Invalid name option: {0}".format(k))
|
||||||
|
|
||||||
|
if not all(self.ports):
|
||||||
|
self.ports_cmp = None
|
||||||
|
else:
|
||||||
|
if (self.ports[0] < 1 or self.ports[1] < 1):
|
||||||
|
raise ValueError("Port numbers must be positive: {0[0]}-{0[1]}".format(ports))
|
||||||
|
|
||||||
|
if (self.ports[0] > self.ports[1]):
|
||||||
|
raise ValueError(
|
||||||
|
"The low port must be smaller than the high port: {0[0]}-{0[1]}".format(ports))
|
||||||
|
|
||||||
|
self.ports_cmp = self.ports
|
||||||
|
|
||||||
def set_protocol(self, protocol):
|
def set_protocol(self, protocol):
|
||||||
"""
|
"""
|
||||||
Set the criteria for matching the IP protocol.
|
Set the criteria for matching the IP protocol.
|
||||||
|
@ -29,11 +29,11 @@ class RBACRuleQuery(rulequery.RuleQuery):
|
|||||||
"""Query the RBAC rules."""
|
"""Query the RBAC rules."""
|
||||||
|
|
||||||
def __init__(self, policy,
|
def __init__(self, policy,
|
||||||
ruletype=[],
|
ruletype=None,
|
||||||
source="", source_regex=False, source_indirect=True,
|
source=None, source_regex=False, source_indirect=True,
|
||||||
target="", target_regex=False, target_indirect=True,
|
target=None, target_regex=False, target_indirect=True,
|
||||||
tclass="", tclass_regex=False,
|
tclass=None, tclass_regex=False,
|
||||||
default="", default_regex=False):
|
default=None, default_regex=False):
|
||||||
"""
|
"""
|
||||||
Parameters:
|
Parameters:
|
||||||
policy The policy to query.
|
policy The policy to query.
|
||||||
|
@ -26,8 +26,8 @@ class RoleQuery(compquery.ComponentQuery):
|
|||||||
"""Query SELinux policy roles."""
|
"""Query SELinux policy roles."""
|
||||||
|
|
||||||
def __init__(self, policy,
|
def __init__(self, policy,
|
||||||
name="", name_regex=False,
|
name=None, name_regex=False,
|
||||||
types=set(), types_equal=False, types_regex=False):
|
types=None, types_equal=False, types_regex=False):
|
||||||
"""
|
"""
|
||||||
Parameter:
|
Parameter:
|
||||||
policy The policy to query.
|
policy The policy to query.
|
||||||
|
@ -27,9 +27,9 @@ class SensitivityQuery(mixins.MatchAlias, compquery.ComponentQuery):
|
|||||||
"""Query MLS Sensitivities"""
|
"""Query MLS Sensitivities"""
|
||||||
|
|
||||||
def __init__(self, policy,
|
def __init__(self, policy,
|
||||||
name="", name_regex=False,
|
name=None, name_regex=False,
|
||||||
alias="", alias_regex=False,
|
alias=None, alias_regex=False,
|
||||||
sens="", sens_dom=False, sens_domby=False):
|
sens=None, sens_dom=False, sens_domby=False):
|
||||||
"""
|
"""
|
||||||
Parameters:
|
Parameters:
|
||||||
name The name of the category to match.
|
name The name of the category to match.
|
||||||
|
@ -29,13 +29,13 @@ class TERuleQuery(mixins.MatchPermission, rulequery.RuleQuery):
|
|||||||
"""Query the Type Enforcement rules."""
|
"""Query the Type Enforcement rules."""
|
||||||
|
|
||||||
def __init__(self, policy,
|
def __init__(self, policy,
|
||||||
ruletype=[],
|
ruletype=None,
|
||||||
source="", source_regex=False, source_indirect=True,
|
source=None, source_regex=False, source_indirect=True,
|
||||||
target="", target_regex=False, target_indirect=True,
|
target=None, target_regex=False, target_indirect=True,
|
||||||
tclass="", tclass_regex=False,
|
tclass=None, tclass_regex=False,
|
||||||
perms=set(), perms_equal=False,
|
perms=None, perms_equal=False,
|
||||||
default="", default_regex=False,
|
default=None, default_regex=False,
|
||||||
boolean=set(), boolean_regex=False, boolean_equal=False):
|
boolean=None, boolean_regex=False, boolean_equal=False):
|
||||||
"""
|
"""
|
||||||
Parameter:
|
Parameter:
|
||||||
policy The policy to query.
|
policy The policy to query.
|
||||||
|
@ -26,8 +26,8 @@ class TypeAttributeQuery(compquery.ComponentQuery):
|
|||||||
"""Query SELinux policy type attributes."""
|
"""Query SELinux policy type attributes."""
|
||||||
|
|
||||||
def __init__(self, policy,
|
def __init__(self, policy,
|
||||||
name="", name_regex=False,
|
name=None, name_regex=False,
|
||||||
types=set(), types_equal=False, types_regex=False):
|
types=None, types_equal=False, types_regex=False):
|
||||||
"""
|
"""
|
||||||
Parameter:
|
Parameter:
|
||||||
policy The policy to query.
|
policy The policy to query.
|
||||||
|
@ -27,9 +27,9 @@ class TypeQuery(mixins.MatchAlias, compquery.ComponentQuery):
|
|||||||
"""Query SELinux policy types."""
|
"""Query SELinux policy types."""
|
||||||
|
|
||||||
def __init__(self, policy,
|
def __init__(self, policy,
|
||||||
name="", name_regex=False,
|
name=None, name_regex=False,
|
||||||
alias="", alias_regex=False,
|
alias=None, alias_regex=False,
|
||||||
attrs=set(), attrs_equal=False, attrs_regex=False,
|
attrs=None, attrs_equal=False, attrs_regex=False,
|
||||||
permissive=False, match_permissive=False):
|
permissive=False, match_permissive=False):
|
||||||
"""
|
"""
|
||||||
Parameter:
|
Parameter:
|
||||||
|
@ -27,10 +27,10 @@ class UserQuery(compquery.ComponentQuery):
|
|||||||
"""Query SELinux policy users."""
|
"""Query SELinux policy users."""
|
||||||
|
|
||||||
def __init__(self, policy,
|
def __init__(self, policy,
|
||||||
name="", name_regex=False,
|
name=None, name_regex=False,
|
||||||
roles=set(), roles_equal=False, roles_regex=False,
|
roles=None, roles_equal=False, roles_regex=False,
|
||||||
level="", level_dom=False, level_domby=False, level_incomp=False,
|
level=None, level_dom=False, level_domby=False, level_incomp=False,
|
||||||
range_="", range_overlap=False, range_subset=False,
|
range_=None, range_overlap=False, range_subset=False,
|
||||||
range_superset=False, range_proper=False):
|
range_superset=False, range_proper=False):
|
||||||
"""
|
"""
|
||||||
Parameter:
|
Parameter:
|
||||||
|
Loading…
Reference in New Issue
Block a user