sciform 0.36.0__py3-none-any.whl → 0.38.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,7 +5,6 @@ from __future__ import annotations
5
5
  from dataclasses import replace
6
6
  from decimal import Decimal
7
7
  from typing import TYPE_CHECKING, cast
8
- from warnings import warn
9
8
 
10
9
  from sciform.api.formatted_number import FormattedNumber
11
10
  from sciform.format_utils.exponents import get_exp_str, get_val_unc_exp
@@ -25,9 +24,9 @@ from sciform.format_utils.rounding import get_round_dec_place, round_val_unc
25
24
  from sciform.formatting.parser import parse_val_unc_from_input
26
25
  from sciform.options.conversion import finalize_populated_options, populate_options
27
26
  from sciform.options.option_types import (
28
- AutoExpVal,
29
27
  ExpFormatEnum,
30
28
  ExpModeEnum,
29
+ ExpValEnum,
31
30
  RoundModeEnum,
32
31
  SignModeEnum,
33
32
  )
@@ -79,7 +78,7 @@ def format_non_finite(num: Decimal, options: FinalizedOptions) -> str:
79
78
  exp_mode = options.exp_mode
80
79
 
81
80
  exp_val = options.exp_val
82
- if options.exp_val is AutoExpVal:
81
+ if options.exp_val is ExpValEnum.AUTO:
83
82
  exp_val = 0
84
83
 
85
84
  exp_str = get_exp_str(
@@ -180,7 +179,7 @@ def format_num(num: Decimal, options: FinalizedOptions) -> str:
180
179
  return result
181
180
 
182
181
 
183
- def format_val_unc(val: Decimal, unc: Decimal, options: FinalizedOptions) -> str:
182
+ def format_val_unc(val: Decimal, unc: Decimal, options: FinalizedOptions) -> str: # noqa: PLR0915
184
183
  """Format value/uncertainty pair according to input options."""
185
184
  exp_mode = options.exp_mode
186
185
 
@@ -190,13 +189,6 @@ def format_val_unc(val: Decimal, unc: Decimal, options: FinalizedOptions) -> str
190
189
  )
191
190
  raise NotImplementedError(msg)
192
191
 
193
- if options.round_mode is RoundModeEnum.DEC_PLACE:
194
- msg = (
195
- "Precision round mode not available for value/uncertainty formatting. "
196
- "Rounding is always applied as significant figures for the uncertainty."
197
- )
198
- warn(msg, stacklevel=2)
199
-
200
192
  unc = abs(unc)
201
193
  if exp_mode is ExpModeEnum.PERCENT:
202
194
  val *= 100
@@ -210,31 +202,72 @@ def format_val_unc(val: Decimal, unc: Decimal, options: FinalizedOptions) -> str
210
202
  """
211
203
  exp_mode = ExpModeEnum.FIXEDPOINT
212
204
 
213
- """
214
- We round twice in case the first rounding changes the digits place
215
- to which we need to round. E.g. rounding 999.999 ± 123.456 to two
216
- significant figures will lead to 1000.000 ± 0120.000 on the first
217
- pass, but we must re-round to get 1000.000 ± 0100.000.
218
- """
219
- val_rounded, unc_rounded, _ = round_val_unc(
220
- val,
221
- unc,
222
- options.ndigits,
223
- use_pdg_sig_figs=options.pdg_sig_figs,
224
- )
225
- val_rounded, unc_rounded, round_digit = round_val_unc(
226
- val_rounded,
227
- unc_rounded,
228
- options.ndigits,
229
- use_pdg_sig_figs=options.pdg_sig_figs,
230
- )
205
+ if options.round_mode is RoundModeEnum.DEC_PLACE:
206
+ """
207
+ We calculate the exponent twice in case rounding the mantissa changes the
208
+ required exponent. For example, 0.0999 ± 0.0999 displayed in scientific notation
209
+ would be (9.99 ± 9.99)e-02 but rounded to zero digits-past-the-decimal gives
210
+ (10 ± 10)e-02, so we need to recalculate the exponent to get (1 ± 1)e-01.
211
+ """
212
+ exp_val = get_val_unc_exp(
213
+ val,
214
+ unc,
215
+ options.exp_mode,
216
+ options.exp_val,
217
+ )
218
+ val_mantissa = val * Decimal(10) ** (-Decimal(exp_val))
219
+ unc_mantissa = unc * Decimal(10) ** (-Decimal(exp_val))
220
+ val_mantissa_rounded, unc_mantissa_rounded, _ = round_val_unc(
221
+ val_mantissa,
222
+ unc_mantissa,
223
+ options.round_mode,
224
+ options.ndigits,
225
+ )
226
+ val_rounded = val_mantissa_rounded * Decimal(10) ** Decimal(exp_val)
227
+ unc_rounded = unc_mantissa_rounded * Decimal(10) ** Decimal(exp_val)
228
+ exp_val = get_val_unc_exp(
229
+ val_rounded,
230
+ unc_rounded,
231
+ options.exp_mode,
232
+ options.exp_val,
233
+ )
234
+ """
235
+ ndigits that will be used for separate digits-past-the-decimal rounding for the
236
+ value and uncertainty.
237
+ """
238
+ ndigits = options.ndigits
239
+ else:
240
+ """
241
+ We round twice in case the first rounding changes the digits place to which we
242
+ need to round. E.g. rounding 0.0999 ± 0.0999 to one significant figure would
243
+ naively result in rounding to the -2 place, leaving us with 0.10 ± 0.10. But the
244
+ -2 place actually corresponds to two significant figures, so we re-round to the
245
+ -1 place to get 0.1 ± 0.1.
246
+ """
247
+ val_rounded, unc_rounded, _ = round_val_unc(
248
+ val,
249
+ unc,
250
+ options.round_mode,
251
+ options.ndigits,
252
+ )
253
+ val_rounded, unc_rounded, round_digit = round_val_unc(
254
+ val_rounded,
255
+ unc_rounded,
256
+ options.round_mode,
257
+ options.ndigits,
258
+ )
231
259
 
232
- exp_val = get_val_unc_exp(
233
- val_rounded,
234
- unc_rounded,
235
- options.exp_mode,
236
- options.exp_val,
237
- )
260
+ exp_val = get_val_unc_exp(
261
+ val_rounded,
262
+ unc_rounded,
263
+ options.exp_mode,
264
+ options.exp_val,
265
+ )
266
+ """
267
+ ndigits that will be used for separate digits-past-the-decimal rounding for the
268
+ value and uncertainty.
269
+ """
270
+ ndigits = -round_digit + exp_val
238
271
 
239
272
  val_mantissa, _, _ = get_mantissa_exp_base(
240
273
  val_rounded,
@@ -254,8 +287,6 @@ def format_val_unc(val: Decimal, unc: Decimal, options: FinalizedOptions) -> str
254
287
  left_pad_matching=options.left_pad_matching,
255
288
  )
256
289
 
257
- ndigits = -round_digit + exp_val
258
-
259
290
  """
260
291
  We will format the val and unc mantissas
261
292
  * using decimal place rounding mode with the ndigits calculated
@@ -294,8 +325,6 @@ def format_val_unc(val: Decimal, unc: Decimal, options: FinalizedOptions) -> str
294
325
  val_unc_str = construct_val_unc_str(
295
326
  val_mantissa_str=val_mantissa_str,
296
327
  unc_mantissa_str=unc_mantissa_str,
297
- val_mantissa=val_mantissa,
298
- unc_mantissa=unc_mantissa,
299
328
  decimal_separator=options.decimal_separator,
300
329
  paren_uncertainty=options.paren_uncertainty,
301
330
  pm_whitespace=options.pm_whitespace,
@@ -90,6 +90,7 @@ def populate_options(input_options: InputOptions) -> PopulatedOptions:
90
90
 
91
91
  key_to_enum_dict = {
92
92
  "exp_mode": option_types.ExpModeEnum,
93
+ "exp_val": option_types.ExpValEnum,
93
94
  "round_mode": option_types.RoundModeEnum,
94
95
  "upper_separator": option_types.SeparatorEnum,
95
96
  "decimal_separator": option_types.SeparatorEnum,
@@ -104,7 +105,7 @@ def finalize_populated_options(populated_options: PopulatedOptions) -> Finalized
104
105
  """Convert PopulatedOptions into FinalizedOptions with enum values."""
105
106
  kwargs = populated_options.as_dict()
106
107
  for key, value in kwargs.items():
107
- if key in key_to_enum_dict:
108
+ if key in key_to_enum_dict and isinstance(value, str):
108
109
  enum = key_to_enum_dict[key]
109
110
  kwargs[key] = option_types.mode_str_to_enum(value, enum)
110
111
  return FinalizedOptions(**kwargs)
@@ -10,8 +10,6 @@ from __future__ import annotations
10
10
  from dataclasses import dataclass
11
11
  from typing import TYPE_CHECKING
12
12
 
13
- from sciform.options.validation import validate_options
14
-
15
13
  if TYPE_CHECKING: # pragma: no cover
16
14
  from sciform.options import option_types
17
15
 
@@ -21,9 +19,9 @@ class FinalizedOptions:
21
19
  """Rendered options: All options populated and using Enum instead of Literal."""
22
20
 
23
21
  exp_mode: option_types.ExpModeEnum
24
- exp_val: int | type(option_types.AutoExpVal)
22
+ exp_val: int | option_types.ExpValEnum
25
23
  round_mode: option_types.RoundModeEnum
26
- ndigits: int | type(option_types.AutoDigits)
24
+ ndigits: int
27
25
  upper_separator: option_types.UpperSeparatorEnums
28
26
  decimal_separator: option_types.DecimalSeparatorEnums
29
27
  lower_separator: option_types.LowerSeparatorEnums
@@ -38,10 +36,6 @@ class FinalizedOptions:
38
36
  superscript: bool
39
37
  nan_inf_exp: bool
40
38
  paren_uncertainty: bool
41
- pdg_sig_figs: bool
42
39
  left_pad_matching: bool
43
40
  paren_uncertainty_trim: bool
44
41
  pm_whitespace: bool
45
-
46
- def __post_init__(self: FinalizedOptions) -> None:
47
- validate_options(self, none_allowed=False)
@@ -1,13 +1,12 @@
1
1
  """Global Options."""
2
2
 
3
- from sciform.options import option_types
4
3
  from sciform.options.populated_options import PopulatedOptions
5
4
 
6
5
  PKG_DEFAULT_OPTIONS = PopulatedOptions(
7
6
  exp_mode="fixed_point",
8
- exp_val=option_types.AutoExpVal,
9
- round_mode="sig_fig",
10
- ndigits=option_types.AutoDigits,
7
+ exp_val="auto",
8
+ round_mode="all",
9
+ ndigits=2,
11
10
  upper_separator="",
12
11
  decimal_separator=".",
13
12
  lower_separator="",
@@ -22,7 +21,6 @@ PKG_DEFAULT_OPTIONS = PopulatedOptions(
22
21
  superscript=False,
23
22
  nan_inf_exp=False,
24
23
  paren_uncertainty=False,
25
- pdg_sig_figs=False,
26
24
  left_pad_matching=False,
27
25
  paren_uncertainty_trim=True,
28
26
  pm_whitespace=True,
@@ -51,9 +51,9 @@ class InputOptions:
51
51
  """ # noqa: E501
52
52
 
53
53
  exp_mode: option_types.ExpMode | None = None
54
- exp_val: int | type(option_types.AutoExpVal) | None = None
54
+ exp_val: int | option_types.ExpVal | None = None
55
55
  round_mode: option_types.RoundMode | None = None
56
- ndigits: int | type(option_types.AutoDigits) | None = None
56
+ ndigits: int | None = None
57
57
  upper_separator: option_types.UpperSeparators | None = None
58
58
  decimal_separator: option_types.DecimalSeparators | None = None
59
59
  lower_separator: option_types.LowerSeparators | None = None
@@ -68,7 +68,6 @@ class InputOptions:
68
68
  superscript: bool | None = None
69
69
  nan_inf_exp: bool | None = None
70
70
  paren_uncertainty: bool | None = None
71
- pdg_sig_figs: bool | None = None
72
71
  left_pad_matching: bool | None = None
73
72
  paren_uncertainty_trim: bool | None = None
74
73
  pm_whitespace: bool | None = None
@@ -5,51 +5,6 @@ from __future__ import annotations
5
5
  from enum import Enum
6
6
  from typing import Literal, TypeVar
7
7
 
8
-
9
- class SentinelMeta(type):
10
- """Sentinel metaclass, __repr__ returns class name."""
11
-
12
- def __repr__(cls: SentinelMeta) -> str:
13
- return cls.__name__
14
-
15
-
16
- class AutoExpVal(metaclass=SentinelMeta):
17
- """
18
- Flag for auto-exponent calculation mode.
19
-
20
- * For scientific exponent mode the base-10 exponent is selected so
21
- that the mantissa ``m`` satisfies ``1 <= m < 10``.
22
- * For engineering exponent mode the base-10 exponent is chosen so
23
- that it is an integer multiple of 3 and the mantissa ``m``
24
- satisfies ``1 <= m < 1000``.
25
- * For shifted engineering exponent mode the base-10 exponent is
26
- chosen so that it is an integer multiple of 3 and the mantissa
27
- ``m`` satisfies ``0.1 <= m < 100``.
28
- * For binary exponent mode the base-2 exponent is chosen so that
29
- the mantissa ``m`` satisfies ``1 <= m < 2``.
30
- * For binary IEC exponent mode the base-2 exponent is chosen so
31
- that the mantissa ``m`` satisfies ``1 <= m < 1024 = 2**10``.
32
- """
33
-
34
-
35
- class AutoDigits(metaclass=SentinelMeta):
36
- """
37
- Flag for auto ndigits calculation mode.
38
-
39
- In both sig fig and ndigits round modes this auto ndigits
40
- option chooses the ndigits so that the least significant digit of
41
- the input number will be displayed.
42
- For example the number 123.456789 would be displayed with either 9
43
- significant figures or 6 digits past the decimal point so that in
44
- either case all digits are shown.
45
-
46
- When used with sig fig rounding and in combination with the
47
- ``pdg_sig_figs`` option, the number of significant figures will be
48
- chosen to be one or two in accordance with the Particle Data Group
49
- algorithm.
50
- """
51
-
52
-
53
8
  LeftPadChar = Literal[" ", "0"]
54
9
 
55
10
 
@@ -101,7 +56,7 @@ LowerSeparatorEnums = Literal[
101
56
  ]
102
57
 
103
58
 
104
- RoundMode = Literal["sig_fig", "dec_place"]
59
+ RoundMode = Literal["sig_fig", "dec_place", "all", "pdg"]
105
60
 
106
61
 
107
62
  class RoundModeEnum(str, Enum):
@@ -109,6 +64,8 @@ class RoundModeEnum(str, Enum):
109
64
 
110
65
  SIG_FIG = "sig_fig"
111
66
  DEC_PLACE = "dec_place"
67
+ ALL = "all"
68
+ PDG = "pdg"
112
69
 
113
70
 
114
71
  ExpMode = Literal[
@@ -145,6 +102,15 @@ class ExpFormatEnum(str, Enum):
145
102
  PARTS_PER = "parts_per"
146
103
 
147
104
 
105
+ ExpVal = Literal["auto"]
106
+
107
+
108
+ class ExpValEnum(str, Enum):
109
+ """Exponent value Enum."""
110
+
111
+ AUTO = "auto"
112
+
113
+
148
114
  T = TypeVar("T", bound=Enum)
149
115
 
150
116
 
@@ -44,7 +44,7 @@ class PopulatedOptions:
44
44
  >>> print(formatter.populated_options)
45
45
  PopulatedOptions(
46
46
  'exp_mode': 'engineering',
47
- 'exp_val': AutoExpVal,
47
+ 'exp_val': 'auto',
48
48
  'round_mode': 'sig_fig',
49
49
  'ndigits': 2,
50
50
  'upper_separator': '',
@@ -61,13 +61,12 @@ class PopulatedOptions:
61
61
  'superscript': True,
62
62
  'nan_inf_exp': False,
63
63
  'paren_uncertainty': False,
64
- 'pdg_sig_figs': False,
65
64
  'left_pad_matching': False,
66
65
  'paren_uncertainty_trim': True,
67
66
  'pm_whitespace': True,
68
67
  )
69
68
  >>> print(formatter.populated_options.as_dict())
70
- {'exp_mode': 'engineering', 'exp_val': AutoExpVal, 'round_mode': 'sig_fig', 'ndigits': 2, 'upper_separator': '', 'decimal_separator': '.', 'lower_separator': '', 'sign_mode': '-', 'left_pad_char': ' ', 'left_pad_dec_place': 0, 'exp_format': 'standard', 'extra_si_prefixes': {}, 'extra_iec_prefixes': {}, 'extra_parts_per_forms': {}, 'capitalize': False, 'superscript': True, 'nan_inf_exp': False, 'paren_uncertainty': False, 'pdg_sig_figs': False, 'left_pad_matching': False, 'paren_uncertainty_trim': True, 'pm_whitespace': True}
69
+ {'exp_mode': 'engineering', 'exp_val': 'auto', 'round_mode': 'sig_fig', 'ndigits': 2, 'upper_separator': '', 'decimal_separator': '.', 'lower_separator': '', 'sign_mode': '-', 'left_pad_char': ' ', 'left_pad_dec_place': 0, 'exp_format': 'standard', 'extra_si_prefixes': {}, 'extra_iec_prefixes': {}, 'extra_parts_per_forms': {}, 'capitalize': False, 'superscript': True, 'nan_inf_exp': False, 'paren_uncertainty': False, 'left_pad_matching': False, 'paren_uncertainty_trim': True, 'pm_whitespace': True}
71
70
 
72
71
  Note that :class:`PopulatedOptions` lacks the ``add_c_prefix``,
73
72
  ``add_small_si_prefixes`` and ``add_ppth_form`` options present
@@ -93,9 +92,9 @@ class PopulatedOptions:
93
92
  """ # noqa: E501
94
93
 
95
94
  exp_mode: option_types.ExpMode
96
- exp_val: int | type(option_types.AutoExpVal)
95
+ exp_val: int | option_types.ExpVal
97
96
  round_mode: option_types.RoundMode
98
- ndigits: int | type(option_types.AutoDigits)
97
+ ndigits: int
99
98
  upper_separator: option_types.UpperSeparators
100
99
  decimal_separator: option_types.DecimalSeparators
101
100
  lower_separator: option_types.LowerSeparators
@@ -110,7 +109,6 @@ class PopulatedOptions:
110
109
  superscript: bool
111
110
  nan_inf_exp: bool
112
111
  paren_uncertainty: bool
113
- pdg_sig_figs: bool
114
112
  left_pad_matching: bool
115
113
  paren_uncertainty_trim: bool
116
114
  pm_whitespace: bool
@@ -14,7 +14,7 @@ if TYPE_CHECKING: # pragma: no cover
14
14
 
15
15
 
16
16
  def validate_options(
17
- options: InputOptions | PopulatedOptions | FinalizedOptions,
17
+ options: InputOptions | PopulatedOptions,
18
18
  *,
19
19
  none_allowed: bool,
20
20
  ) -> None:
@@ -31,59 +31,49 @@ allowed_round_modes = get_args(option_types.RoundMode)
31
31
 
32
32
 
33
33
  def validate_rounding(
34
- options: InputOptions | PopulatedOptions | FinalizedOptions,
34
+ options: InputOptions | PopulatedOptions,
35
35
  *,
36
36
  none_allowed: bool,
37
37
  ) -> None:
38
38
  r"""Validate ndigits if round_mode == "sig_fig"."""
39
- if (
40
- not (none_allowed and options.round_mode is None)
41
- and options.round_mode not in allowed_round_modes
42
- ):
43
- msg = f"round_mode must be in {allowed_round_modes}, not {options.round_mode}."
44
- raise ValueError(msg)
45
-
46
- if not (none_allowed and options.ndigits is None) and not isinstance(
47
- options.ndigits,
48
- (int, type(option_types.AutoDigits)),
49
- ):
50
- msg = f'ndigits must be an "int" or "AutoDigits", not {options.ndigits}.'
39
+ if none_allowed and options.ndigits is None:
40
+ pass
41
+ elif not isinstance(options.ndigits, int):
42
+ msg = f"ndigits must be an int, not {options.ndigits}."
51
43
  raise TypeError(msg)
52
44
 
53
- if (
54
- not (none_allowed and options.round_mode is None)
55
- and options.round_mode == "sig_fig"
56
- and isinstance(options.ndigits, int)
57
- and options.ndigits < 1
58
- ):
59
- msg = f"ndigits must be >= 1 for sig fig rounding, not {options.ndigits}."
60
- raise ValueError(msg)
45
+ if none_allowed and options.round_mode is None:
46
+ pass
47
+ else:
48
+ if options.round_mode not in allowed_round_modes:
49
+ msg = (
50
+ f"round_mode must be in {allowed_round_modes}, not "
51
+ f"{options.round_mode}."
52
+ )
53
+ raise ValueError(msg)
54
+ if options.round_mode == "sig_fig" and options.ndigits < 1:
55
+ msg = f"ndigits must be >= 1 for sig fig rounding, not {options.ndigits}."
56
+ raise ValueError(msg)
61
57
 
62
58
 
63
59
  allowed_exp_modes = get_args(option_types.ExpMode)
64
- allowed_exp_val_types = (int, type(option_types.AutoExpVal), type(None))
65
60
  allowed_exp_formats = get_args(option_types.ExpFormat)
66
61
 
67
62
 
68
- def validate_exp_options(
63
+ def validate_exp_val(
69
64
  options: InputOptions | PopulatedOptions | FinalizedOptions,
70
65
  *,
71
66
  none_allowed: bool,
72
67
  ) -> None:
73
- """Validate exponent options."""
74
- if (
75
- not (none_allowed and options.exp_mode is None)
76
- and options.exp_mode not in allowed_exp_modes
77
- ):
78
- msg = f"exp_mode must be in {allowed_exp_modes}, not {options.exp_mode}."
79
- raise ValueError(msg)
80
-
81
- if not (none_allowed and options.exp_val is None):
82
- if not isinstance(options.exp_val, allowed_exp_val_types):
83
- msg = f"exp_val must be an int, AutoExpVal, or None, not {options.exp_val}."
68
+ """Validate exponent value."""
69
+ if none_allowed and options.exp_val is None:
70
+ pass
71
+ else:
72
+ if not isinstance(options.exp_val, int) and options.exp_val != "auto":
73
+ msg = f"exp_val must be an int, 'auto', or None, not {options.exp_val}."
84
74
  raise TypeError(msg)
85
75
 
86
- if options.exp_val is not option_types.AutoExpVal:
76
+ if options.exp_val != "auto":
87
77
  if options.exp_mode in ["fixed_point", "percent"] and options.exp_val != 0:
88
78
  msg = (
89
79
  f"Exponent must must be 0, not exp_val={options.exp_val}, for "
@@ -106,10 +96,24 @@ def validate_exp_options(
106
96
  )
107
97
  raise ValueError(msg)
108
98
 
109
- if (
110
- not (none_allowed and options.exp_format is None)
111
- and options.exp_format not in allowed_exp_formats
112
- ):
99
+
100
+ def validate_exp_options(
101
+ options: InputOptions | PopulatedOptions | FinalizedOptions,
102
+ *,
103
+ none_allowed: bool,
104
+ ) -> None:
105
+ """Validate exponent options."""
106
+ if none_allowed and options.exp_mode is None:
107
+ pass
108
+ elif options.exp_mode not in allowed_exp_modes:
109
+ msg = f"exp_mode must be in {allowed_exp_modes}, not {options.exp_mode}."
110
+ raise ValueError(msg)
111
+
112
+ validate_exp_val(options, none_allowed=none_allowed)
113
+
114
+ if none_allowed and options.exp_format is None:
115
+ pass
116
+ elif options.exp_format not in allowed_exp_formats:
113
117
  msg = (
114
118
  f"{options.exp_format} must be in {allowed_exp_formats}, not "
115
119
  f"{options.exp_format}."
@@ -126,10 +130,9 @@ def validate_sign_mode(
126
130
  none_allowed: bool,
127
131
  ) -> None:
128
132
  r"""Validate ndigits if round_mode == "sig_fig"."""
129
- if (
130
- not (none_allowed and options.sign_mode is None)
131
- and options.sign_mode not in allowed_sign_modes
132
- ):
133
+ if none_allowed and options.sign_mode is None:
134
+ pass
135
+ elif options.sign_mode not in allowed_sign_modes:
133
136
  msg = f"sign_mode must be in {allowed_sign_modes}, not {options.sign_mode}."
134
137
  raise ValueError(msg)
135
138
 
@@ -140,7 +143,9 @@ def validate_separator_options(
140
143
  none_allowed: bool,
141
144
  ) -> None:
142
145
  """Validate separator user input."""
143
- if not (none_allowed and options.upper_separator is None):
146
+ if none_allowed and options.upper_separator is None:
147
+ pass
148
+ else:
144
149
  if options.upper_separator not in get_args(option_types.UpperSeparators):
145
150
  msg = (
146
151
  f"upper_separator must be in "
@@ -155,9 +160,9 @@ def validate_separator_options(
155
160
  )
156
161
  raise ValueError(msg)
157
162
 
158
- if not (none_allowed and options.decimal_separator is None) and (
159
- options.decimal_separator not in get_args(option_types.DecimalSeparators)
160
- ):
163
+ if none_allowed and options.decimal_separator is None:
164
+ pass
165
+ elif options.decimal_separator not in get_args(option_types.DecimalSeparators):
161
166
  msg = (
162
167
  f"decimal_separator must be in "
163
168
  f"{get_args(option_types.DecimalSeparators)}, not "
@@ -165,9 +170,9 @@ def validate_separator_options(
165
170
  )
166
171
  raise ValueError(msg)
167
172
 
168
- if not (none_allowed and options.lower_separator is None) and (
169
- options.lower_separator not in get_args(option_types.LowerSeparators)
170
- ):
173
+ if none_allowed and options.lower_separator is None:
174
+ pass
175
+ elif options.lower_separator not in get_args(option_types.LowerSeparators):
171
176
  msg = (
172
177
  f"lower_separator must be in {get_args(option_types.LowerSeparators)}, "
173
178
  f"not {options.lower_separator}."
@@ -188,7 +193,9 @@ def validate_extra_translations(
188
193
  ]
189
194
 
190
195
  for translation_dict in translations_dicts:
191
- if not (none_allowed and translation_dict is None):
196
+ if none_allowed and translation_dict is None:
197
+ pass
198
+ else:
192
199
  for key, value in translation_dict.items():
193
200
  if not isinstance(key, int):
194
201
  msg = f'Translation dictionary keys must be integers, not "{key}".'
@@ -208,16 +215,19 @@ def validate_left_pad_options(
208
215
  none_allowed: bool,
209
216
  ) -> None:
210
217
  """Validate left padding options."""
211
- dec_place_msg = (
212
- f"left_pad_dec_place must an an int >= 0, not {options.left_pad_dec_place}."
213
- )
214
- if not (none_allowed and options.left_pad_dec_place is None):
218
+ if none_allowed and options.left_pad_dec_place is None:
219
+ pass
220
+ else:
221
+ dec_place_msg = (
222
+ f"left_pad_dec_place must an an int >= 0, not {options.left_pad_dec_place}."
223
+ )
215
224
  if not isinstance(options.left_pad_dec_place, int):
216
225
  raise TypeError(dec_place_msg)
217
226
  if options.left_pad_dec_place < 0:
218
227
  raise ValueError(dec_place_msg)
219
- if not (
220
- none_allowed and options.left_pad_char is None
221
- ) and options.left_pad_char not in [0, "0", " "]:
228
+
229
+ if none_allowed and options.left_pad_char is None:
230
+ pass
231
+ elif options.left_pad_char not in [0, "0", " "]:
222
232
  msg = f'left_pad_char must be in [" ", "0", 0], not {options.left_pad_char}.'
223
233
  raise ValueError(msg)