Skip to content

Commit 31e9b02

Browse files
bumped version number to 0.0.5, added %E, fixed bool/type capitalization.
1 parent 0e5e8bf commit 31e9b02

File tree

6 files changed

+45
-37
lines changed

6 files changed

+45
-37
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
All notable changes to the pyprintf project will be documented in this file.
44

5+
## [0.0.5] - 2025-04-17
6+
7+
* Added support for uppercase `E` in scientific notation output for floating-point numbers through the `%E` format specifier (e.g., `1.234500E+02`), alongside the existing lowercase `e` format (`%e`).
8+
* Updated documentation to clarify that Python booleans are displayed as capitalized strings (`True`/`False`) when converted to strings.
9+
* Improved type name handling to properly respect Python's standard type name capitalization (e.g., `list`, `dict`, `NoneType`) when using `T` format (`%T`).
10+
511
## [0.0.4] - 2025-04-16
612

713
* Removed conflicting line in pyproject.toml - Programming Status :: Python :: 3.11

README.md

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -146,24 +146,24 @@ These elements can appear in a placeholder in a specific order between the `%` a
146146

147147
This single character at the end of the placeholder determines how the corresponding argument will be interpreted and formatted.
148148

149-
| Specifier | Description | Python Example | Output |
150-
| --------- | ----------------------------------------------------- | ----------------------------------------- | -------------------- |
151-
| `%%` | Outputs a literal percent sign | `sprintf("%%")` | `%` |
152-
| `%b` | Integer in binary format | `sprintf("%b", 10)` | `1010` |
153-
| `%c` | Integer as Unicode character | `sprintf("%c", 65)` | `A` |
154-
| `%d`/`%i` | Signed decimal integer | `sprintf("%d", 123)` | `123` |
155-
| `%e` | Floating point in scientific notation (lowercase "e") | `sprintf("%e", 123.45)` | `1.234500e+02` |
156-
| `%u` | Unsigned decimal integer (32-bit wrap) | `sprintf("%u", -5)` | `4294967291` |
157-
| `%f` | Floating point with decimal precision | `sprintf("%.2f", 3.14159)` | `3.14` |
158-
| `%g` | Adaptive float formatting | `sprintf("%.3g", 1234.56)` | `1.23e+03` |
159-
| `%o` | Integer in octal format | `sprintf("%o", 10)` | `12` |
160-
| `%s` | String output | `sprintf("%s", "hello")` | `hello` |
161-
| `%t` | Boolean (`"true"`/`"false"` lowercase strings) | `sprintf("%t", True)` | `true` |
162-
| `%T` | Python type name | `sprintf("%T", [])` | `list` |
163-
| `%v` | Primitive value representation | `sprintf("%v", 5)` | `5` |
164-
| `%x` | Integer in lowercase hexadecimal | `sprintf("%x", 255)` | `ff` |
165-
| `%X` | Integer in uppercase hexadecimal | `sprintf("%X", 255)` | `FF` |
166-
| `%j` | Python object in JSON format | `sprintf("%j", {"a": 1})` | `{"a": 1}` |
149+
| Specifier | Description | Python Example | Output |
150+
| --------- | ------------------------------------------------------------ | ----------------------------------------- | -------------------- |
151+
| `%%` | Outputs a literal percent sign | `sprintf("%%")` | `%` |
152+
| `b` | Integer in binary format | `sprintf("%b", 10)` | `1010` |
153+
| `c` | Integer as Unicode character | `sprintf("%c", 65)` | `A` |
154+
| `d`/`i` | Signed decimal integer | `sprintf("%d", 123)` | `123` |
155+
| `e` | Floating point in scientific notation (lowercase "e") | `sprintf("%e", 123.45)` | `1.234500e+02` |
156+
| `E` | Floating point in scientific notation (uppercase "E") | `sprintf("%E", 123.45)` | `1.234500E+02` |
157+
| `f` | Floating point with decimal precision | `sprintf("%.2f", 3.14159)` | `3.14` |
158+
| `g` | Adaptive float formatting | `sprintf("%.3g", 1234.56)` | `1.23e+03` |
159+
| `o` | Integer in octal format | `sprintf("%o", 10)` | `12` |
160+
| `s` | String output | `sprintf("%s", "hello")` | `hello` |
161+
| `t` | Boolean (`"True"`/`"False"` capitalized strings) | `sprintf("%t", True)` | `True` |
162+
| `T` | Python type name (`"List"`/`"NoneType"` capitalized strings) | `sprintf("%T", [])` | `List` |
163+
| `u` | Unsigned decimal integer (32-bit wrap) | `sprintf("%u", -5)` | `4294967291` |
164+
| `x` | Integer in lowercase hexadecimal | `sprintf("%x", 255)` | `ff` |
165+
| `X` | Integer in uppercase hexadecimal | `sprintf("%X", 255)` | `FF` |
166+
| `j` | Python object in JSON format | `sprintf("%j", {"a": 1})` | `{"a": 1}` |
167167

168168
## Features
169169

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ maintainers = [
3636
name = "pyprintf"
3737
readme = "README.md"
3838
requires-python = ">=3.10"
39-
version = "0.0.4"
39+
version = "0.0.5"
4040

4141
[project.urls]
4242
"Bug Tracker" = "https://github.com/playfulsparkle/pyprintf/issues"

src/pyprintf/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@
99
from .core import sprintf, vsprintf, config
1010

1111
__all__ = ["sprintf", "vsprintf", "config"]
12-
__version__ = "0.0.4"
12+
__version__ = "0.0.5"

src/pyprintf/core.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -531,9 +531,9 @@ def sprintf_format(
531531
try:
532532
arg = json.dumps(arg, indent=indent if not indent else None)
533533
except:
534-
arg = "null"
534+
arg = "None"
535535

536-
elif placeholder.type == "e": # Exponential notation
536+
elif placeholder.type in ("e", "E"):
537537
try:
538538
if placeholder.precision:
539539
try:
@@ -555,6 +555,8 @@ def sprintf_format(
555555
# Regular scientific notation with precision
556556
arg = f"{float_val:.{precision}e}"
557557

558+
arg = arg.upper() if placeholder.type == "E" else arg
559+
558560
except (ValueError, TypeError):
559561
arg = "0.000000e+00"
560562

@@ -630,17 +632,17 @@ def sprintf_format(
630632
arg = arg[: int(placeholder.precision)]
631633

632634
elif placeholder.type == "t":
633-
arg = str(arg).lower()
635+
arg = str(arg).capitalize()
634636
match arg:
635637
case "0" | "":
636-
arg = "false"
638+
arg = "False"
637639
case "1":
638-
arg = "true"
640+
arg = "True"
639641
if placeholder.precision:
640642
arg = arg[: int(placeholder.precision)]
641643

642644
elif placeholder.type == "T":
643-
arg = type(arg).__name__.lower() if arg is not None else "nonetype"
645+
arg = type(arg).__name__.lower() if arg is not None else "NoneType"
644646
if placeholder.precision:
645647
arg = arg[: int(placeholder.precision)]
646648

@@ -669,8 +671,8 @@ def sprintf_format(
669671
if not hex_str: # Handle zero case
670672
hex_str = "0"
671673

672-
hex_str: str = hex_str.upper() if placeholder.type == "X" else hex_str
673-
arg = hex_str
674+
arg: str = hex_str.upper() if placeholder.type == "X" else hex_str
675+
674676
except (ValueError, TypeError):
675677
arg = "0"
676678

tests/test_sprintf.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -108,33 +108,33 @@ def test_format_named_and_positional_index_arguments(self):
108108

109109
class TestPlaceholderBoolean:
110110
def test_format_true_as_true(self):
111-
assert sprintf("%t", True) == "true"
111+
assert sprintf("%t", True) == "True"
112112

113113
def test_format_true_as_t_with_precision_1(self):
114-
assert sprintf("%.1t", True) == "t"
114+
assert sprintf("%.1t", True) == "T"
115115

116116
def test_format_the_string_true_as_true(self):
117-
assert sprintf("%t", "True") == "true"
117+
assert sprintf("%t", "True") == "True"
118118

119119
def test_format_the_number_1_as_true(self):
120-
assert sprintf("%t", 1) == "true"
120+
assert sprintf("%t", 1) == "True"
121121

122122
def test_format_false_as_false(self):
123-
assert sprintf("%t", False) == "false"
123+
assert sprintf("%t", False) == "False"
124124

125125
def test_format_false_as_f_with_precision_1(self):
126-
assert sprintf("%.1t", False) == "f"
126+
assert sprintf("%.1t", False) == "F"
127127

128128
def test_format_an_empty_string_as_false(self):
129-
assert sprintf("%t", "") == "false"
129+
assert sprintf("%t", "") == "False"
130130

131131
def test_format_the_number_0_as_false(self):
132-
assert sprintf("%t", "") == "false"
132+
assert sprintf("%t", "") == "False"
133133

134134

135135
class TestPlaceholderType:
136136
def test_format_none_as_nonetype(self):
137-
assert sprintf("%T", None) == "nonetype"
137+
assert sprintf("%T", None) == "NoneType"
138138

139139
def test_format_a_boolean_as_boolean(self):
140140
assert sprintf("%T", True) == "bool"

0 commit comments

Comments
 (0)