laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/35851?usp=email )
Change subject: pylint: construct.py
......................................................................
pylint: construct.py
pySim/construct.py:47:0: W0311: Bad indentation. Found 16 spaces, expected 12 (bad-indentation)
pySim/construct.py:59:0: W0311: Bad indentation. Found 16 spaces, expected 12 (bad-indentation)
pySim/construct.py:82:0: W0311: Bad indentation. Found 16 spaces, expected 12 (bad-indentation)
pySim/construct.py:1:0: C0114: Missing module docstring (missing-module-docstring)
pySim/construct.py:14:0: W0105: String statement has no effect (pointless-string-statement)
pySim/construct.py:178:29: W0613: Unused argument 'instr' (unused-argument)
pySim/construct.py:199:15: C0121: Comparison 'codepoint_prefix == None' should be 'codepoint_prefix is None' (singleton-comparison)
pySim/construct.py:269:15: C0121: Comparison 'v == False' should be 'v is False' if checking for the singleton value False, or 'not v' if testing for falsiness (singleton-comparison)
pySim/construct.py:271:17: C0121: Comparison 'v == True' should be 'v is True' if checking for the singleton value True, or 'v' if testing for truthiness (singleton-comparison)
pySim/construct.py:385:15: C0123: Use isinstance() rather than type() for a typecheck. (unidiomatic-typecheck)
pySim/construct.py:392:15: C0123: Use isinstance() rather than type() for a typecheck. (unidiomatic-typecheck)
pySim/construct.py:408:11: C0123: Use isinstance() rather than type() for a typecheck. (unidiomatic-typecheck)
pySim/construct.py:421:7: R1701: Consider merging these isinstance calls to isinstance(c, (Container, dict)) (consider-merging-isinstance)
pySim/construct.py:444:11: R1729: Use a generator instead 'all(v == 255 for v in raw_bin_data)' (use-a-generator)
pySim/construct.py:434:81: W0613: Unused argument 'exclude_prefix' (unused-argument)
pySim/construct.py:544:12: W0707: Consider explicitly re-raising using 'raise IntegerError(str(e), path=path) from e' (raise-missing-from)
pySim/construct.py:561:8: R1731: Consider using 'nbytes = max(nbytes, minlen)' instead of unnecessary if block (consider-using-max-builtin)
pySim/construct.py:573:12: W0707: Consider explicitly re-raising using 'raise IntegerError(str(e), path=path) from e' (raise-missing-from)
pySim/construct.py:3:0: C0411: standard import "import typing" should be placed before "from construct.lib.containers import Container, ListContainer" (wrong-import-order)
pySim/construct.py:10:0: C0411: third party import "import gsm0338" should be placed before "from pySim.utils import b2h, h2b, swap_nibbles" (wrong-import-order)
pySim/construct.py:11:0: C0411: standard import "import codecs" should be placed before "from construct.lib.containers import Container, ListContainer" (wrong-import-order)
pySim/construct.py:12:0: C0411: standard import "import ipaddress" should be placed before "from construct.lib.containers import Container, ListContainer" (wrong-import-order)
pySim/construct.py:7:0: W0611: Unused BitwisableString imported from construct.core (unused-import)
Change-Id: Ic8a06d65a7bcff9ef399fe4e7e5d82f271c946bb
---
M pySim/construct.py
1 file changed, 63 insertions(+), 28 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/51/35851/1
diff --git a/pySim/construct.py b/pySim/construct.py
index 8ef7941..881f1f2 100644
--- a/pySim/construct.py
+++ b/pySim/construct.py
@@ -1,17 +1,20 @@
-from construct.lib.containers import Container, ListContainer
-from construct.core import EnumIntegerString
+"""Utility code related to the integration of the 'construct' declarative parser."""
+
import typing
-from construct import Adapter, Prefixed, Int8ub, GreedyBytes, Default, Flag, Byte, Construct, Enum
-from construct import BitsInteger, BitStruct, Bytes, StreamError, stream_read_entire, stream_write
-from construct import SizeofError, IntegerError, swapbytes
-from construct.core import evaluate, BitwisableString
-from construct.lib import integertypes
-from pySim.utils import b2h, h2b, swap_nibbles
-import gsm0338
import codecs
import ipaddress
-"""Utility code related to the integration of the 'construct' declarative parser."""
+import gsm0338
+
+from construct.lib.containers import Container, ListContainer
+from construct.core import EnumIntegerString
+from construct import Adapter, Prefixed, Int8ub, GreedyBytes, Default, Flag, Byte, Construct, Enum
+from construct import BitsInteger, BitStruct, Bytes, StreamError, stream_read_entire, stream_write
+from construct import SizeofError, IntegerError, swapbytes
+from construct.core import evaluate
+from construct.lib import integertypes
+
+from pySim.utils import b2h, h2b, swap_nibbles
# (C) 2021-2022 by Harald Welte <laforge(a)osmocom.org>
#
@@ -44,7 +47,7 @@
def _decode(self, obj, context, path):
# In case the string contains only 0xff bytes we interpret it as an empty string
if obj == b'\xff' * len(obj):
- return ""
+ return ""
return codecs.decode(obj, "utf-8")
def _encode(self, obj, context, path):
@@ -56,7 +59,7 @@
def _decode(self, obj, context, path):
# In case the string contains only 0xff bytes we interpret it as an empty string
if obj == b'\xff' * len(obj):
- return ""
+ return ""
# one of the magic bytes of TS 102 221 Annex A
if obj[0] in [0x80, 0x81, 0x82]:
ad = Ucs2Adapter(GreedyBytes)
@@ -79,7 +82,7 @@
def _decode(self, obj, context, path):
# In case the string contains only 0xff bytes we interpret it as an empty string
if obj == b'\xff' * len(obj):
- return ""
+ return ""
if obj[0] == 0x80:
# TS 102 221 Annex A Variant 1
return codecs.decode(obj[1:], 'utf_16_be')
@@ -177,7 +180,7 @@
def _encode_variant1(instr: str) -> bytes:
"""Encode according to TS 102 221 Annex A Variant 1"""
- return b'\x80' + codecs.encode(obj, 'utf_16_be')
+ return b'\x80' + codecs.encode(instr, 'utf_16_be')
def _encode_variant2(instr: str) -> bytes:
"""Encode according to TS 102 221 Annex A Variant 2"""
@@ -196,7 +199,7 @@
assert codepoint_prefix == c_prefix
enc = (0x80 + (c_codepoint & 0x7f)).to_bytes(1, byteorder='big')
chars += enc
- if codepoint_prefix == None:
+ if codepoint_prefix is None:
codepoint_prefix = 0
return hdr + codepoint_prefix.to_bytes(1, byteorder='big') + chars
@@ -266,9 +269,9 @@
# skip all private entries
if k.startswith('_'):
continue
- if v == False:
+ if v is False:
obj[k] = True
- elif v == True:
+ elif v is True:
obj[k] = False
return obj
@@ -382,14 +385,14 @@
self.min_len = min_len
def _decode(self, obj, context, path):
- assert type(obj) == bytes
+ assert isinstance(obj, bytes)
# pad with suppressed/missing bytes
if len(obj) < self.total_length:
obj += self.default_value * (self.total_length - len(obj))
return int.from_bytes(obj, 'big')
def _encode(self, obj, context, path):
- assert type(obj) == int
+ assert isinstance(obj, int)
obj = obj.to_bytes(self.total_length, 'big')
# remove trailing bytes if they are zero
while len(obj) > self.min_len and obj[-1] == self.default_value[0]:
@@ -405,20 +408,20 @@
for (key, value) in d.items():
if key.startswith(exclude_prefix):
continue
- if type(value) is dict:
+ if isinstance(value, dict):
res[key] = filter_dict(value)
else:
res[key] = value
return res
-def normalize_construct(c):
+def normalize_construct(c, exclude_prefix: str = '_'):
"""Convert a construct specific type to a related base type, mostly useful
so we can serialize it."""
# we need to include the filter_dict as we otherwise get elements like this
# in the dict: '_io': <_io.BytesIO object at 0x7fdb64e05860> which we cannot json-serialize
- c = filter_dict(c)
- if isinstance(c, Container) or isinstance(c, dict):
+ c = filter_dict(c, exclude_prefix)
+ if isinstance(c, (Container, dict)):
r = {k: normalize_construct(v) for (k, v) in c.items()}
elif isinstance(c, ListContainer):
r = [normalize_construct(x) for x in c]
@@ -441,11 +444,11 @@
# if the input is all-ff, this means the content is undefined. Let's avoid passing StreamError
# exceptions in those situations (which might occur if a length field 0xff is 255 but then there's
# actually less bytes in the remainder of the file.
- if all([v == 0xff for v in raw_bin_data]):
+ if all(v == 0xff for v in raw_bin_data):
return None
else:
raise e
- return normalize_construct(parsed)
+ return normalize_construct(parsed, exclude_prefix)
def build_construct(c, decoded_data, context: dict = {}):
"""Helper function to handle total_len."""
@@ -558,8 +561,7 @@
# round up to the minimum number
# of bytes we anticipate
- if nbytes < minlen:
- nbytes = minlen
+ nbytes = max(nbytes, minlen)
return nbytes
@@ -570,7 +572,7 @@
try:
data = obj.to_bytes(length, byteorder='big', signed=self.signed)
except ValueError as e:
- raise IntegerError(str(e), path=path)
+ raise IntegerError(str(e), path=path) from e
if evaluate(self.swapped, context):
data = swapbytes(data)
stream_write(stream, data, length, path)
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/35851?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: Ic8a06d65a7bcff9ef399fe4e7e5d82f271c946bb
Gerrit-Change-Number: 35851
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge(a)osmocom.org>
Gerrit-MessageType: newchange
laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/35824?usp=email )
Change subject: pylint: transport/__init__.py
......................................................................
pylint: transport/__init__.py
pySim/transport/__init__.py:139:0: C0325: Unnecessary parens after 'if' keyword (superfluous-parens)
Change-Id: Ibeeb7d6fde40bb37774bbd09ad185203ac7bcb48
---
M pySim/transport/__init__.py
1 file changed, 12 insertions(+), 1 deletion(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/24/35824/1
diff --git a/pySim/transport/__init__.py b/pySim/transport/__init__.py
index dcecfdd..dd06af8 100644
--- a/pySim/transport/__init__.py
+++ b/pySim/transport/__init__.py
@@ -136,7 +136,7 @@
# available. There are two SWs commonly used for this 9fxx (sim) and 61xx (usim), where
# xx is the number of response bytes available.
# See also:
- if (sw is not None):
+ if sw is not None:
while ((sw[0:2] == '9f') or (sw[0:2] == '61')):
# SW1=9F: 3GPP TS 51.011 9.4.1, Responses to commands which are correctly executed
# SW1=61: ISO/IEC 7816-4, Table 5 — General meaning of the interindustry values of SW1-SW2
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/35824?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: Ibeeb7d6fde40bb37774bbd09ad185203ac7bcb48
Gerrit-Change-Number: 35824
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge(a)osmocom.org>
Gerrit-MessageType: newchange
laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/35823?usp=email )
Change subject: pylint: transport/serial.py
......................................................................
pylint: transport/serial.py
pySim/transport/serial.py:54:0: C0325: Unnecessary parens after 'if' keyword (superfluous-parens)
pySim/transport/serial.py:89:0: C0325: Unnecessary parens after 'if' keyword (superfluous-parens)
pySim/transport/serial.py:225:0: C0325: Unnecessary parens after 'while' keyword (superfluous-parens)
pySim/transport/serial.py:63:12: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return)
pySim/transport/serial.py:106:8: R1720: Unnecessary "elif" after "raise", remove the leading "el" from "elif" (no-else-raise)
pySim/transport/serial.py:124:12: W0707: Consider explicitly re-raising using 'except Exception as exc' and 'raise ValueError('Invalid reset pin %s' % self._rst_pin) from exc' (raise-missing-from)
pySim/transport/serial.py:204:12: R1723: Unnecessary "elif" after "break", remove the leading "el" from "elif" (no-else-break)
pySim/transport/serial.py:20:0: C0411: standard import "import time" should be placed before "import serial" (wrong-import-order)
pySim/transport/serial.py:21:0: C0411: standard import "import os" should be placed before "import serial" (wrong-import-order)
pySim/transport/serial.py:22:0: C0411: standard import "import argparse" should be placed before "import serial" (wrong-import-order)
pySim/transport/serial.py:23:0: C0411: standard import "from typing import Optional" should be placed before "import serial" (wrong-import-order)
Change-Id: I82ef12492615a18a13cbdecf0371b3a5d02bbd5c
---
M pySim/transport/serial.py
1 file changed, 30 insertions(+), 10 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/23/35823/1
diff --git a/pySim/transport/serial.py b/pySim/transport/serial.py
index 06a082a..b4eddcd 100644
--- a/pySim/transport/serial.py
+++ b/pySim/transport/serial.py
@@ -16,11 +16,11 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-import serial
import time
import os
import argparse
from typing import Optional
+import serial
from pySim.exceptions import NoCardError, ProtocolError
from pySim.transport import LinkBase
@@ -51,7 +51,7 @@
self._atr = None
def __del__(self):
- if (hasattr(self, "_sl")):
+ if hasattr(self, "_sl"):
self._sl.close()
def wait_for_card(self, timeout: Optional[int] = None, newcardonly: bool = False):
@@ -62,8 +62,7 @@
self.reset_card()
if not newcardonly:
return
- else:
- existing = True
+ existing = True
except NoCardError:
pass
@@ -86,7 +85,7 @@
# Tolerate a couple of protocol error ... can happen if
# we try when the card is 'half' inserted
pe += 1
- if (pe > 2):
+ if pe > 2:
raise
# Timed out ...
@@ -105,7 +104,7 @@
rv = self._reset_card()
if rv == 0:
raise NoCardError()
- elif rv < 0:
+ if rv < 0:
raise ProtocolError()
return rv
@@ -120,8 +119,8 @@
try:
rst_meth = rst_meth_map[self._rst_pin[1:]]
rst_val = rst_val_map[self._rst_pin[0]]
- except:
- raise ValueError('Invalid reset pin %s' % self._rst_pin)
+ except Exception as exc:
+ raise ValueError('Invalid reset pin %s' % self._rst_pin) from exc
rst_meth(rst_val)
time.sleep(0.1) # 100 ms
@@ -203,7 +202,7 @@
b = self._rx_byte()
if ord(b) == pdu[1]:
break
- elif b != '\x60':
+ if b != '\x60':
# Ok, it 'could' be SW1
sw1 = b
sw2 = self._rx_byte()
@@ -222,7 +221,7 @@
to_recv = data_len - len(pdu) + 5 + 2
data = bytes(0)
- while (len(data) < to_recv):
+ while len(data) < to_recv:
b = self._rx_byte()
if (to_recv == 2) and (b == '\x60'): # Ignore NIL if we have no RX data (hack ?)
continue
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/35823?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I82ef12492615a18a13cbdecf0371b3a5d02bbd5c
Gerrit-Change-Number: 35823
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge(a)osmocom.org>
Gerrit-MessageType: newchange
laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/35830?usp=email )
Change subject: pylint: apdu/__init__.py
......................................................................
pylint: apdu/__init__.py
pySim/apdu/__init__.py:41:0: W0105: String statement has no effect (pointless-string-statement)
pySim/apdu/__init__.py:55:4: C0204: Metaclass class method __new__ should have 'mcs' as first argument (bad-mcs-classmethod-argument)
pySim/apdu/__init__.py:187:8: R1705: Unnecessary "elif" after "return", remove the leading "el" from "elif" (no-else-return)
pySim/apdu/__init__.py:200:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return)
pySim/apdu/__init__.py:208:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return)
pySim/apdu/__init__.py:216:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return)
pySim/apdu/__init__.py:224:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return)
pySim/apdu/__init__.py:239:11: C0117: Consider changing "not 'p1' in self.cmd_dict" to "'p1' not in self.cmd_dict" (unnecessary-negation)
pySim/apdu/__init__.py:295:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return)
pySim/apdu/__init__.py:313:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return)
pySim/apdu/__init__.py:416:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return)
pySim/apdu/__init__.py:429:12: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return)
pySim/apdu/__init__.py:455:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return)
pySim/apdu/__init__.py:31:0: C0411: standard import "import typing" should be placed before "from termcolor import colored" (wrong-import-order)
pySim/apdu/__init__.py:32:0: C0411: standard import "from typing import List, Dict, Optional" should be placed before "from termcolor import colored" (wrong-import-order)
Change-Id: I5657912df474f3ed0e277458a8eb33e28aeb2927
---
M pySim/apdu/__init__.py
1 file changed, 40 insertions(+), 22 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/30/35830/1
diff --git a/pySim/apdu/__init__.py b/pySim/apdu/__init__.py
index b884e23..f5b7852 100644
--- a/pySim/apdu/__init__.py
+++ b/pySim/apdu/__init__.py
@@ -1,4 +1,3 @@
-# coding=utf-8
"""APDU (and TPDU) parser for UICC/USIM/ISIM cards.
The File (and its classes) represent the structure / hierarchy
@@ -27,12 +26,13 @@
import abc
-from termcolor import colored
import typing
from typing import List, Dict, Optional
+from termcolor import colored
-from construct import *
+from construct import Byte, GreedyBytes
from construct import Optional as COptional
+
from pySim.construct import *
from pySim.utils import *
from pySim.runtime import RuntimeLchan, RuntimeState, lchan_nr_from_cla
@@ -52,8 +52,8 @@
class ApduCommandMeta(abc.ABCMeta):
"""A meta-class that we can use to set some class variables when declaring
a derived class of ApduCommand."""
- def __new__(metacls, name, bases, namespace, **kwargs):
- x = super().__new__(metacls, name, bases, namespace)
+ def __new__(mcs, name, bases, namespace, **kwargs):
+ x = super().__new__(mcs, name, bases, namespace)
x._name = namespace.get('name', kwargs.get('n', None))
x._ins = namespace.get('ins', kwargs.get('ins', None))
x._cla = namespace.get('cla', kwargs.get('cla', None))
@@ -187,44 +187,39 @@
if apdu_case in [1, 2]:
# data is part of response
return cls(buffer[:5], buffer[5:])
- elif apdu_case in [3, 4]:
+ if apdu_case in [3, 4]:
# data is part of command
lc = buffer[4]
return cls(buffer[:5+lc], buffer[5+lc:])
- else:
- raise ValueError('%s: Invalid APDU Case %u' % (cls.__name__, apdu_case))
+ raise ValueError('%s: Invalid APDU Case %u' % (cls.__name__, apdu_case))
@property
def path(self) -> List[str]:
"""Return (if known) the path as list of files to the file on which this command operates."""
if self.file:
return self.file.fully_qualified_path()
- else:
- return []
+ return []
@property
def path_str(self) -> str:
"""Return (if known) the path as string to the file on which this command operates."""
if self.file:
return self.file.fully_qualified_path_str()
- else:
- return ''
+ return ''
@property
def col_sw(self) -> str:
"""Return the ansi-colorized status word. Green==OK, Red==Error"""
if self.successful:
return colored(b2h(self.sw), 'green')
- else:
- return colored(b2h(self.sw), 'red')
+ return colored(b2h(self.sw), 'red')
@property
def lchan_nr(self) -> int:
"""Logical channel number over which this ApduCommand was transmitted."""
if self.lchan:
return self.lchan.lchan_nr
- else:
- return lchan_nr_from_cla(self.cla)
+ return lchan_nr_from_cla(self.cla)
def __str__(self) -> str:
return '%02u %s(%s): %s' % (self.lchan_nr, type(self).__name__, self.path_str, self.to_dict())
@@ -236,7 +231,7 @@
"""Fall-back function to be called if there is no derived-class-specific
process_global or process_on_lchan method. Uses information from APDU decode."""
self.processed = {}
- if not 'p1' in self.cmd_dict:
+ if 'p1' not in self.cmd_dict:
self.processed = self.to_dict()
else:
self.processed['p1'] = self.cmd_dict['p1']
@@ -428,8 +423,7 @@
apdu = Apdu(icmd, tpdu.rsp)
if self.apdu_handler:
return self.apdu_handler.input(apdu)
- else:
- return Apdu(icmd, tpdu.rsp)
+ return Apdu(icmd, tpdu.rsp)
def input(self, cmd: bytes, rsp: bytes):
if isinstance(cmd, str):
@@ -452,7 +446,6 @@
self.atr = atr
def __str__(self):
- if (self.atr):
+ if self.atr:
return '%s(%s)' % (type(self).__name__, b2h(self.atr))
- else:
- return '%s' % (type(self).__name__)
+ return '%s' % (type(self).__name__)
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/35830?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I5657912df474f3ed0e277458a8eb33e28aeb2927
Gerrit-Change-Number: 35830
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge(a)osmocom.org>
Gerrit-MessageType: newchange