Hello Jenkins Builder,
I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/c/pysim/+/40096?usp=email
to look at the new patch set (#2).
The following approvals got outdated and were removed:
Verified+1 by Jenkins Builder
Change subject: personalization: add param_source.py, implement batch personalization
......................................................................
personalization: add param_source.py, implement batch personalization
Implement pySim.esim.saip.personalization.BatchPersonalization,
generating N eSIM profiles from a preset configuration.
Batch parameters can be fed by a constant, incrementing, random or from
CSV rows: add pySim.esim.saip.param_source.* classes to feed such input
to each of the BatchPersonalization's ConfigurableParameter instances.
Related: SYS#6768
Change-Id: I497c60c101ea0eea980e8b1a4b1f36c0eda39002
---
A pySim/esim/saip/param_source.py
M pySim/esim/saip/personalization.py
2 files changed, 280 insertions(+), 1 deletion(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/96/40096/2
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/40096?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newpatchset
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I497c60c101ea0eea980e8b1a4b1f36c0eda39002
Gerrit-Change-Number: 40096
Gerrit-PatchSet: 2
Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
neels has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/40093?usp=email )
Change subject: personalization: set some typical parameter names
......................................................................
personalization: set some typical parameter names
These names better match what humans expect to read, for example "PIN1"
instead of "Pin1".
(We still fall back to the __class__.__name__ if a subclass omits a
specific name, see the ConfigurableParameter init.)
Change-Id: I31f390d634e58c384589c50a33ca45d6f86d4e10
---
M pySim/esim/saip/personalization.py
1 file changed, 11 insertions(+), 0 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/93/40093/1
diff --git a/pySim/esim/saip/personalization.py b/pySim/esim/saip/personalization.py
index d09be46..a97706f 100644
--- a/pySim/esim/saip/personalization.py
+++ b/pySim/esim/saip/personalization.py
@@ -272,6 +272,7 @@
class Iccid(DecimalParam):
"""ICCID Parameter. Input: string of decimal digits.
If the string of digits is only 18 digits long, add a Luhn check digit."""
+ name = 'ICCID'
min_len = 18
max_len = 20
@@ -290,6 +291,8 @@
class Imsi(DecimalParam):
"""Configurable IMSI. Expects value to be a string of digits. Automatically sets the ACC to
the last digit of the IMSI."""
+
+ name = 'IMSI'
min_len = 6
max_len = 15
@@ -473,9 +476,11 @@
f" cannot find pukCode with keyReference={cls.keyReference}")
class Puk1(Puk):
+ name = 'PUK1'
keyReference = 0x01
class Puk2(Puk):
+ name = 'PUK2'
keyReference = 0x81
class Pin(DecimalHexParam):
@@ -505,9 +510,11 @@
+ f' {cls.get_name()} cannot find pinCode with keyReference={cls.keyReference}')
class Pin1(Pin):
+ name = 'PIN1'
keyReference = 0x01
class Pin2(Pin):
+ name = 'PIN2'
keyReference = 0x81
@classmethod
@@ -523,9 +530,11 @@
+ f' {cls.get_name()} cannot find pinCode with keyReference={cls.keyReference} in {naa=}')
class Adm1(Pin):
+ name = 'ADM1'
keyReference = 0x0A
class Adm2(Pin):
+ name = 'ADM2'
keyReference = 0x0B
class AlgoConfig(ConfigurableParameter):
@@ -561,8 +570,10 @@
class K(BinaryParam, AlgoConfig):
"""use validate_val() from BinaryParam, and apply_val() from AlgoConfig"""
+ name = 'K'
algo_config_key = 'key'
allow_len = int(128/8) # length in bytes (from BinaryParam)
class Opc(K):
+ name = 'OPc'
algo_config_key = 'opc'
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/40093?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I31f390d634e58c384589c50a33ca45d6f86d4e10
Gerrit-Change-Number: 40093
Gerrit-PatchSet: 1
Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de>
neels has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/40095?usp=email )
Change subject: personalization: discover all useful ConfigurableParameter subclasses
......................................................................
personalization: discover all useful ConfigurableParameter subclasses
Discover all non-abstract subclasses of ConfigurableParameter in
ConfigurableParameter.get_all_implementations().
To be able to automatically discover all practically useful
ConfigurableParameter subclasses, introduce the is_abstract flag.
ConfigurableParameter itself sets is_abstract = True, by default
"hiding" subclasses. As soon as a subclass sets is_abstract = False, it
becomes "public". It depends on the calling code to actually implement
that decision -- this flag enables calling code to do so sanely.
For example, the BinaryParam superclass keeps is_abstract = True,
because per se it isn't capable of doing anything. The fully useful K
and Opc subclasses set is_abstract = False.
Implementation choice: I first tried to query an implicit abstract
status via abc / @abstractmethod ways, but it did not match well. A
subclass has no good implicit indicator, we need a flag instead. For
example, a superclass may provide an apply_val() implementation and
hence appear as non-abstract, but it is still not usable because a
specific 'key' member is still None, which various subclasses set.
Related: SYS#6768
Change-Id: I4970657294130b6b65d50ff19ffbb9ebab3be609
---
M pySim/esim/saip/personalization.py
M pySim/utils.py
2 files changed, 30 insertions(+), 1 deletion(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/95/40095/1
diff --git a/pySim/esim/saip/personalization.py b/pySim/esim/saip/personalization.py
index bb6eec3..26fcbf7 100644
--- a/pySim/esim/saip/personalization.py
+++ b/pySim/esim/saip/personalization.py
@@ -20,7 +20,7 @@
from typing import List, Tuple
from osmocom.tlv import camel_to_snake
-from pySim.utils import enc_iccid, enc_imsi, h2b, rpad, sanitize_iccid
+from pySim.utils import enc_iccid, enc_imsi, h2b, rpad, sanitize_iccid, all_subclasses_of
from pySim.esim.saip import ProfileElement, ProfileElementSequence
def remove_unwanted_tuples_from_list(l: List[Tuple], unwanted_keys: List[str]) -> List[Tuple]:
@@ -93,10 +93,14 @@
changed_der = pes.to_der()
"""
+ # for get_all_implementations(), telling callers about all practically useful parameters
+ is_abstract = True
+
# A subclass can set an explicit string as name (like name = "PIN1").
# If name is left None, then __init__() will set self.name to a name derived from the python class name (like
# "pin1"). See also the get_name() classmethod when you have no instance at hand.
name = None
+
allow_types = (str, int, )
allow_chars = None
strip_chars = None
@@ -209,6 +213,15 @@
return (None, None)
return (min(vals), max(vals))
+ @classmethod
+ def get_all_implementations(cls, blacklist=None, allow_abstract=False):
+ # return a set() so that multiple inheritance does not return dups
+ return set(c
+ for c in all_subclasses_of(cls)
+ if ((allow_abstract or not c.is_abstract)
+ and ((not blacklist) or (c not in blacklist)))
+ )
+
class DecimalParam(ConfigurableParameter):
"""Decimal digits. The input value may be a string of decimal digits like '012345', or an int. The output of
@@ -273,6 +286,7 @@
class Iccid(DecimalParam):
"""ICCID Parameter. Input: string of decimal digits.
If the string of digits is only 18 digits long, add a Luhn check digit."""
+ is_abstract = False
name = 'ICCID'
min_len = 18
max_len = 20
@@ -293,6 +307,7 @@
class Imsi(DecimalParam):
"""Configurable IMSI. Expects value to be a string of digits. Automatically sets the ACC to
the last digit of the IMSI."""
+ is_abstract = False
name = 'IMSI'
min_len = 6
@@ -480,10 +495,12 @@
f" cannot find pukCode with keyReference={cls.keyReference}")
class Puk1(Puk):
+ is_abstract = False
name = 'PUK1'
keyReference = 0x01
class Puk2(Puk):
+ is_abstract = False
name = 'PUK2'
keyReference = 0x81
@@ -515,11 +532,13 @@
+ f' {cls.get_name()} cannot find pinCode with keyReference={cls.keyReference}')
class Pin1(Pin):
+ is_abstract = False
name = 'PIN1'
default_value = '0' * 4 # PIN are usually 4 digits
keyReference = 0x01
class Pin2(Pin1):
+ is_abstract = False
name = 'PIN2'
keyReference = 0x81
@@ -536,10 +555,12 @@
+ f' {cls.get_name()} cannot find pinCode with keyReference={cls.keyReference} in {naa=}')
class Adm1(Pin):
+ is_abstract = False
name = 'ADM1'
keyReference = 0x0A
class Adm2(Adm1):
+ is_abstract = False
name = 'ADM2'
keyReference = 0x0B
@@ -561,6 +582,7 @@
class AlgorithmID(DecimalParam, AlgoConfig):
+ is_abstract = False
algo_config_key = 'algorithmID'
allow_len = 1
default_value = 1 # Milenage
@@ -577,6 +599,7 @@
class K(BinaryParam, AlgoConfig):
"""use validate_val() from BinaryParam, and apply_val() from AlgoConfig"""
+ is_abstract = False
name = 'K'
algo_config_key = 'key'
allow_len = int(128/8) # length in bytes (from BinaryParam)
diff --git a/pySim/utils.py b/pySim/utils.py
index 48a9998..ec519a7 100644
--- a/pySim/utils.py
+++ b/pySim/utils.py
@@ -980,3 +980,9 @@
if cla and not cmd.match_cla(cla):
return None
return cmd
+
+
+def all_subclasses_of(cls):
+ for subc in cls.__subclasses__():
+ yield subc
+ yield from all_subclasses_of(subc)
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/40095?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I4970657294130b6b65d50ff19ffbb9ebab3be609
Gerrit-Change-Number: 40095
Gerrit-PatchSet: 1
Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de>
neels has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/40096?usp=email )
Change subject: personalization: add param_source.py, implement batch personalization
......................................................................
personalization: add param_source.py, implement batch personalization
Implement pySim.esim.saip.personalization.BatchPersonalization,
generating N eSIM profiles from a preset configuration.
Batch parameters can be fed by a constant, incrementing, random or from
CSV rows: add pySim.esim.saip.param_source.* classes to feed such input
to each of the BatchPersonalization's ConfigurableParameter instances.
Related: SYS#6768
Change-Id: I497c60c101ea0eea980e8b1a4b1f36c0eda39002
---
A pySim/esim/saip/param_source.py
M pySim/esim/saip/personalization.py
2 files changed, 230 insertions(+), 1 deletion(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/96/40096/1
diff --git a/pySim/esim/saip/param_source.py b/pySim/esim/saip/param_source.py
new file mode 100644
index 0000000..8fce881
--- /dev/null
+++ b/pySim/esim/saip/param_source.py
@@ -0,0 +1,167 @@
+# Implementation of SimAlliance/TCA Interoperable Profile handling: parameter sources for batch personalization.
+#
+# (C) 2025 by sysmocom - s.f.m.c. GmbH <info(a)sysmocom.de>
+#
+# Author: nhofmeyr(a)sysmocom.de
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import random
+from pySim.utils import all_subclasses_of
+
+class ParamSourceExn(Exception):
+ pass
+
+class ParamSourceExhaustedExn(ParamSourceExn):
+ pass
+
+class ParamSourceUndefinedExn(ParamSourceExn):
+ pass
+
+class ParamSource:
+ 'abstract parameter source'
+
+ # This name should be short but descriptive, useful for a user interface, like 'random decimal digits'.
+ name = 'none'
+
+ @classmethod
+ def get_all_implementations(cls, blacklist=None):
+ # return a set() so that multiple inheritance does not return dups
+ return set(c
+ for c in all_subclasses_of(cls)
+ if ((not blacklist) or (c not in blacklist))
+ )
+
+ @classmethod
+ def from_str(cls, s:str):
+ '''if a parameter source defines some string input magic, override this function.
+ For example, a RandomDigitSource derives the number of digits from the string length,
+ so the user can enter '0000' to get a four digit random number.'''
+ return cls(s)
+
+ def get_next(self, csv_row:dict=None):
+ '''return the next value from the parameter source.
+ When there are no more values from the source, raise a ParamSourceExhaustedExn.'''
+ raise ParamSourceExhaustedExn()
+
+
+class ConstantSource(ParamSource):
+ 'one value for all'
+ name = 'constant'
+
+ def __init__(self, val:str):
+ self.val = val
+
+ def get_next(self, csv_row:dict=None):
+ return self.val
+
+class RandomDigitSource(ParamSource):
+ 'return a different sequence of random decimal digits each'
+ name = 'random decimal digits'
+
+ def __init__(self, num_digits, first_value, last_value):
+ 'see from_str()'
+ num_digits = int(num_digits)
+ first_value = int(first_value)
+ last_value = int(last_value)
+ assert num_digits > 0
+ assert first_value <= last_value
+ self.num_digits = num_digits
+ self.val_first_last = (first_value, last_value)
+
+ def get_next(self, csv_row:dict=None):
+ val = random.randint(*self.val_first_last) # TODO secure random source?
+ return self.val_to_digit(val)
+
+ def val_to_digit(self, val:int):
+ return '%0*d' % (self.num_digits, val) # pylint: disable=consider-using-f-string
+
+ @classmethod
+ def from_str(cls, s:str):
+ if '..' in s:
+ first_str, last_str = s.split('..')
+ first_str = first_str.strip()
+ last_str = last_str.strip()
+ else:
+ first_str = s.strip()
+ last_str = None
+
+ first_value = int(first_str)
+ last_value = int(last_str) if last_str is not None else '9' * len(first_str)
+ return cls(num_digits=len(first_str), first_value=first_value, last_value=last_value)
+
+class RandomHexDigitSource(ParamSource):
+ 'return a different sequence of random hexadecimal digits each'
+ name = 'random hexadecimal digits'
+
+ def __init__(self, num_digits):
+ 'see from_str()'
+ num_digits = int(num_digits)
+ if num_digits < 1:
+ raise ValueError('zero number of digits')
+ # hex digits always come in two
+ if (num_digits & 1) != 0:
+ raise ValueError(f'hexadecimal value should have even number of digits, not {num_digits}')
+ self.num_digits = num_digits
+
+ def get_next(self, csv_row:dict=None):
+ val = random.randbytes(self.num_digits // 2) # TODO secure random source?
+ return val
+
+ @classmethod
+ def from_str(cls, s:str):
+ return cls(num_digits=len(s.strip()))
+
+class IncDigitSource(RandomDigitSource):
+ 'incrementing sequence of digits'
+ name = 'incrementing decimal digits'
+
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self.next_val = None
+ self.reset()
+
+ def reset(self):
+ self.next_val = self.val_first_last[0]
+
+ def get_next(self, csv_row:dict=None):
+ val = self.next_val
+ if val is None:
+ raise ParamSourceExhaustedExn()
+
+ returnval = self.val_to_digit(val)
+
+ val += 1
+ if val > self.val_first_last[1]:
+ self.next_val = None
+ else:
+ self.next_val = val
+
+ return returnval
+
+class CsvSource(ParamSource):
+ 'apply a column from a CSV row, as passed in to ParamSource.get_next(csv_row)'
+ name = 'from CSV'
+
+ def __init__(self, csv_column, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self.csv_column = csv_column
+
+ def get_next(self, csv_row:dict=None):
+ val = None
+ if csv_row:
+ val = csv_row.get(self.csv_column)
+ if not val:
+ raise ParamSourceUndefinedExn(f'no value for CSV column {self.csv_column!r}')
+ return val
diff --git a/pySim/esim/saip/personalization.py b/pySim/esim/saip/personalization.py
index 26fcbf7..160962f 100644
--- a/pySim/esim/saip/personalization.py
+++ b/pySim/esim/saip/personalization.py
@@ -17,11 +17,13 @@
import abc
import io
-from typing import List, Tuple
+import copy
+from typing import List, Tuple, Generator
from osmocom.tlv import camel_to_snake
from pySim.utils import enc_iccid, enc_imsi, h2b, rpad, sanitize_iccid, all_subclasses_of
from pySim.esim.saip import ProfileElement, ProfileElementSequence
+from pySim.esim.saip import param_source
def remove_unwanted_tuples_from_list(l: List[Tuple], unwanted_keys: List[str]) -> List[Tuple]:
"""In a list of tuples, remove all tuples whose first part equals 'unwanted_key'."""
@@ -608,3 +610,63 @@
class Opc(K):
name = 'OPc'
algo_config_key = 'opc'
+
+
+class BatchPersonalization:
+
+ class ParamAndSrc:
+ 'tie a ConfigurableParameter to a source of actual values'
+ def __init__(self, param:ConfigurableParameter, src:param_source.ParamSource):
+ self.param = param
+ self.src = src
+
+ def __init__(self,
+ n:int,
+ src_pes:ProfileElementSequence,
+ params:list[ParamAndSrc]=None,
+ csv_rows:Generator=None,
+ ):
+ self.n = n
+ self.params = params or []
+ self.src_pes = src_pes
+ self.csv_rows = csv_rows
+
+ def add_param_and_src(self, param:ConfigurableParameter, src:param_source.ParamSource):
+ self.params.append(BatchPersonalization.ParamAndSrc(param=param, src=src))
+
+ def generate_profiles(self):
+ # get first row of CSV: column names
+ csv_columns = None
+ if self.csv_rows:
+ try:
+ csv_columns = next(self.csv_rows)
+ except StopIteration as e:
+ raise ValueError('the input CSV file appears to be empty') from e
+
+ for i in range(self.n):
+ csv_row = None
+ if self.csv_rows and csv_columns:
+ try:
+ csv_row_list = next(self.csv_rows)
+ except StopIteration as e:
+ raise ValueError(f'not enough rows in the input CSV for eSIM nr {i+1} of {self.n}') from e
+
+ csv_row = dict(zip(csv_columns, csv_row_list))
+
+ pes = copy.deepcopy(self.src_pes)
+
+ for p in self.params:
+ try:
+ input_value = p.src.get_next(csv_row=csv_row)
+ assert input_value is not None
+ value = p.param.__class__.validate_val(input_value)
+ p.param.__class__.apply_val(pes, value)
+ except (
+ TypeError,
+ ValueError,
+ KeyError,
+ ) as e:
+ raise ValueError(f'{p.param.name} fed by {p.src.name}: {e}'
+ f' (input_value={p.param.input_value!r} value={p.param.value!r})') from e
+
+ yield pes
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/40096?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I497c60c101ea0eea980e8b1a4b1f36c0eda39002
Gerrit-Change-Number: 40096
Gerrit-PatchSet: 1
Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de>
Attention is currently required from: laforge.
neels has posted comments on this change by neels. ( https://gerrit.osmocom.org/c/pysim/+/39745?usp=email )
Change subject: [5/6] personalization: refactor AlgorithmID, K, Opc
......................................................................
Patch Set 4:
(1 comment)
File pySim/esim/saip/personalization.py:
https://gerrit.osmocom.org/c/pysim/+/39745/comment/d2c44a7d_af409c41?usp=em… :
PS3, Line 551: allow_len = int(128/8) # length in bytes (from BinaryParam)
> just look at the pysim-shell code for setting the values on a sysmoISIM card: […]
I'm sorry, I do not comprehend this code snippet at all...
Can you decipher for me, I just need to know: what valid lengths can any K have for TUAK (and any other algo)?
(matching a K length to a chosen algo will have to be done by a later integrity check, because there currently is no relation between separate ConfigurableParameters)
We could also merge this patch now, because it supports Milenage, and fix TUAK later...?
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/39745?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: comment
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I6296fdcfd5d2ed313c4aade57ff43cc362375848
Gerrit-Change-Number: 39745
Gerrit-PatchSet: 4
Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Attention: laforge <laforge(a)osmocom.org>
Gerrit-Comment-Date: Sat, 19 Apr 2025 22:13:23 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: neels <nhofmeyr(a)sysmocom.de>
Comment-In-Reply-To: laforge <laforge(a)osmocom.org>
Attention is currently required from: laforge.
neels has posted comments on this change by neels. ( https://gerrit.osmocom.org/c/pysim/+/39744?usp=email )
Change subject: [4/6] personalization: refactor Pin, Adm
......................................................................
Patch Set 4:
(1 comment)
File pySim/esim/saip/personalization.py:
https://gerrit.osmocom.org/c/pysim/+/39744/comment/6ef7717e_f3b9e05f?usp=em… :
PS3, Line 408: return (pe for pe in l if pe.type == wanted_type)
> * I think from an ISO7816 and UICC point of view it's sadly not correct to limit to MF. […]
This patch is trying to not modify prior behavior.
The aim is to remove code dup between class Pin and class AppPin.
- Prior code happens to limit to MF for PIN1.
- Prior API happens to produce a mix of ProfileElementList and plain py lists.
If these prior conditions are wrong, I would like to fix them outside of this patch.
I created issue https://osmocom.org/issues/6770 for the MF question.
and https://osmocom.org/issues/6771 for the lists question.
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/39744?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: comment
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I54aef10b6d4309398d4b779a3740a7d706d68603
Gerrit-Change-Number: 39744
Gerrit-PatchSet: 4
Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Attention: laforge <laforge(a)osmocom.org>
Gerrit-Comment-Date: Sat, 19 Apr 2025 21:57:13 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: neels <nhofmeyr(a)sysmocom.de>
Comment-In-Reply-To: laforge <laforge(a)osmocom.org>
Attention is currently required from: dexter, fixeria, laforge.
neels has posted comments on this change by neels. ( https://gerrit.osmocom.org/c/pysim/+/39742?usp=email )
Change subject: [2/6] personalization: refactor ConfigurableParameter, Iccid, Imsi
......................................................................
Patch Set 7:
(3 comments)
File pySim/esim/saip/personalization.py:
https://gerrit.osmocom.org/c/pysim/+/39742/comment/2c294888_fba24441?usp=em… :
PS6, Line 117: If self.value is None, first call self.validate() to generate a sanitized self.value from self.input_value.
> I see how this creates a misunderstanding: I always write API docs in the "imperative mood", which i […]
Done
File pySim/esim/saip/personalization.py:
https://gerrit.osmocom.org/c/pysim/+/39742/comment/0538f7c2_358f139f?usp=em… :
PS7, Line 67: =
> shouldn't that be a double-equals (also below)? to me it looks like an assignment rather than a com […]
wow, a log string in a printf in example code in an api comment ... =)
but ok
https://gerrit.osmocom.org/c/pysim/+/39742/comment/d5946cd5_28545b40?usp=em… :
PS7, Line 100: allow_types = (str, int, )
> Does the comma with empty element imply that None is a vaid input value? In that case, I'd prefer a […]
no, the trailing comma does not add a third item.
It's just that i like trailing commas for easier editing and use them where i can.
Also I have this behavior from:
a single-entry list *does* work as my_list = [foo], but tuple braces don't.
This makes a single-entry tuple:
my_tuple = (23, )
another_tuple = tuple((23, ))
This not:
not_my_tuple = (23) # an int
also_not = tuple(23) # TypeError
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/39742?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: comment
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I6522be4c463e34897ca9bff2309b3706a88b3ce8
Gerrit-Change-Number: 39742
Gerrit-PatchSet: 7
Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: dexter <pmaier(a)sysmocom.de>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-CC: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Attention: laforge <laforge(a)osmocom.org>
Gerrit-Attention: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Attention: dexter <pmaier(a)sysmocom.de>
Gerrit-Comment-Date: Sat, 19 Apr 2025 21:17:47 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: neels <nhofmeyr(a)sysmocom.de>
Comment-In-Reply-To: laforge <laforge(a)osmocom.org>
Comment-In-Reply-To: dexter <pmaier(a)sysmocom.de>
Attention is currently required from: fixeria, laforge.
Hello Jenkins Builder,
I'd like you to reexamine a change. Please visit
https://gerrit.osmocom.org/c/pysim/+/39741?usp=email
to look at the new patch set (#9).
The following approvals got outdated and were removed:
Verified+1 by Jenkins Builder
Change subject: [1/6] personalization: refactor: drop ClassVarMeta use
......................................................................
[1/6] personalization: refactor: drop ClassVarMeta use
Drop the ClassVarMeta/metaclass/ABCMeta stuff -- it doesn't seem to
serve any purpose that is not similarly achieved with plain python
inheritance.
Upcoming patches will use normal inheritance a lot more.
Note that most use of the ClassVarMeta was in the SdKey subclasses, and
that these currently don't actually work. See the fix in patch
I07dfc378705eba1318e9e8652796cbde106c6a52 .
name: set a default name from the python class, as ClassVarMeta did.
Also allow setting an explicit string as name instead, per subclass
implementation (see I31f390d634e58c384589c50a33ca45d6f86d4e10).
Related: SYS#6768
Change-Id: I60ea8fd11fb438ec90ddb08b17b658cbb789c051
---
M pySim/esim/saip/personalization.py
1 file changed, 149 insertions(+), 82 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/41/39741/9
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/39741?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newpatchset
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I60ea8fd11fb438ec90ddb08b17b658cbb789c051
Gerrit-Change-Number: 39741
Gerrit-PatchSet: 9
Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-CC: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-CC: laforge <laforge(a)osmocom.org>
Gerrit-Attention: laforge <laforge(a)osmocom.org>
Gerrit-Attention: fixeria <vyanitskiy(a)sysmocom.de>