pybase64 1.4.1__tar.gz → 1.4.2__tar.gz

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.
Files changed (107) hide show
  1. {pybase64-1.4.1/src/pybase64.egg-info → pybase64-1.4.2}/PKG-INFO +13 -2
  2. {pybase64-1.4.1 → pybase64-1.4.2}/README.rst +9 -0
  3. {pybase64-1.4.1 → pybase64-1.4.2}/base64/.github/workflows/test.yml +4 -2
  4. {pybase64-1.4.1 → pybase64-1.4.2}/base64/cmake/test-arch.c +2 -1
  5. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/neon64/codec.c +4 -10
  6. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/neon64/dec_loop.c +7 -7
  7. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/codec_choose.c +2 -2
  8. {pybase64-1.4.1 → pybase64-1.4.2}/pyproject.toml +10 -12
  9. {pybase64-1.4.1 → pybase64-1.4.2}/setup.py +17 -4
  10. {pybase64-1.4.1 → pybase64-1.4.2}/src/pybase64/__main__.py +34 -41
  11. {pybase64-1.4.1 → pybase64-1.4.2}/src/pybase64/_version.py +1 -1
  12. {pybase64-1.4.1 → pybase64-1.4.2/src/pybase64.egg-info}/PKG-INFO +13 -2
  13. {pybase64-1.4.1 → pybase64-1.4.2}/tests/test_main.py +4 -1
  14. {pybase64-1.4.1 → pybase64-1.4.2}/tests/test_pybase64.py +3 -0
  15. {pybase64-1.4.1 → pybase64-1.4.2}/LICENSE +0 -0
  16. {pybase64-1.4.1 → pybase64-1.4.2}/MANIFEST.in +0 -0
  17. {pybase64-1.4.1 → pybase64-1.4.2}/base64/CMakeLists.txt +0 -0
  18. {pybase64-1.4.1 → pybase64-1.4.2}/base64/LICENSE +0 -0
  19. {pybase64-1.4.1 → pybase64-1.4.2}/base64/Makefile +0 -0
  20. {pybase64-1.4.1 → pybase64-1.4.2}/base64/README.md +0 -0
  21. {pybase64-1.4.1 → pybase64-1.4.2}/base64/base64-benchmarks.png +0 -0
  22. {pybase64-1.4.1 → pybase64-1.4.2}/base64/bin/base64.c +0 -0
  23. {pybase64-1.4.1 → pybase64-1.4.2}/base64/bin/base64.manifest +0 -0
  24. {pybase64-1.4.1 → pybase64-1.4.2}/base64/bin/base64.rc +0 -0
  25. {pybase64-1.4.1 → pybase64-1.4.2}/base64/cmake/Modules/TargetArch.cmake +0 -0
  26. {pybase64-1.4.1 → pybase64-1.4.2}/base64/cmake/Modules/TargetSIMDInstructionSet.cmake +0 -0
  27. {pybase64-1.4.1 → pybase64-1.4.2}/base64/cmake/base64-config.cmake.in +0 -0
  28. {pybase64-1.4.1 → pybase64-1.4.2}/base64/cmake/config.h.in +0 -0
  29. {pybase64-1.4.1 → pybase64-1.4.2}/base64/include/libbase64.h +0 -0
  30. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/avx/codec.c +0 -0
  31. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/avx/enc_loop_asm.c +0 -0
  32. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/avx2/codec.c +0 -0
  33. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/avx2/dec_loop.c +0 -0
  34. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/avx2/dec_reshuffle.c +0 -0
  35. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/avx2/enc_loop.c +0 -0
  36. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/avx2/enc_loop_asm.c +0 -0
  37. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/avx2/enc_reshuffle.c +0 -0
  38. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/avx2/enc_translate.c +0 -0
  39. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/avx512/codec.c +0 -0
  40. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/avx512/enc_loop.c +0 -0
  41. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/avx512/enc_reshuffle_translate.c +0 -0
  42. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/generic/32/dec_loop.c +0 -0
  43. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/generic/32/enc_loop.c +0 -0
  44. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/generic/64/enc_loop.c +0 -0
  45. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/generic/codec.c +0 -0
  46. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/generic/dec_head.c +0 -0
  47. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/generic/dec_tail.c +0 -0
  48. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/generic/enc_head.c +0 -0
  49. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/generic/enc_tail.c +0 -0
  50. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/neon32/codec.c +0 -0
  51. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/neon32/dec_loop.c +0 -0
  52. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/neon32/enc_loop.c +0 -0
  53. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/neon32/enc_reshuffle.c +0 -0
  54. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/neon32/enc_translate.c +0 -0
  55. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/neon64/enc_loop.c +0 -0
  56. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/neon64/enc_loop_asm.c +0 -0
  57. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/neon64/enc_reshuffle.c +0 -0
  58. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/sse41/codec.c +0 -0
  59. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/sse42/codec.c +0 -0
  60. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/ssse3/codec.c +0 -0
  61. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/ssse3/dec_loop.c +0 -0
  62. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/ssse3/dec_reshuffle.c +0 -0
  63. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/ssse3/enc_loop.c +0 -0
  64. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/ssse3/enc_loop_asm.c +0 -0
  65. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/ssse3/enc_reshuffle.c +0 -0
  66. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/arch/ssse3/enc_translate.c +0 -0
  67. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/codecs.h +0 -0
  68. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/env.h +0 -0
  69. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/exports.txt +0 -0
  70. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/lib.c +0 -0
  71. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/lib_openmp.c +0 -0
  72. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/tables/Makefile +0 -0
  73. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/tables/table_dec_32bit.h +0 -0
  74. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/tables/table_enc_12bit.h +0 -0
  75. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/tables/table_enc_12bit.py +0 -0
  76. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/tables/table_generator.c +0 -0
  77. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/tables/tables.c +0 -0
  78. {pybase64-1.4.1 → pybase64-1.4.2}/base64/lib/tables/tables.h +0 -0
  79. {pybase64-1.4.1 → pybase64-1.4.2}/base64/test/CMakeLists.txt +0 -0
  80. {pybase64-1.4.1 → pybase64-1.4.2}/base64/test/Makefile +0 -0
  81. {pybase64-1.4.1 → pybase64-1.4.2}/base64/test/benchmark.c +0 -0
  82. {pybase64-1.4.1 → pybase64-1.4.2}/base64/test/ci/analysis.sh +0 -0
  83. {pybase64-1.4.1 → pybase64-1.4.2}/base64/test/ci/checksums.txt +0 -0
  84. {pybase64-1.4.1 → pybase64-1.4.2}/base64/test/ci/test.sh +0 -0
  85. {pybase64-1.4.1 → pybase64-1.4.2}/base64/test/ci//360/237/230/265/342/200/215/360/237/222/253.bin" +0 -0
  86. {pybase64-1.4.1 → pybase64-1.4.2}/base64/test/codec_supported.c +0 -0
  87. {pybase64-1.4.1 → pybase64-1.4.2}/base64/test/codec_supported.h +0 -0
  88. {pybase64-1.4.1 → pybase64-1.4.2}/base64/test/moby_dick.h +0 -0
  89. {pybase64-1.4.1 → pybase64-1.4.2}/base64/test/moby_dick_base64.txt +0 -0
  90. {pybase64-1.4.1 → pybase64-1.4.2}/base64/test/moby_dick_plain.txt +0 -0
  91. {pybase64-1.4.1 → pybase64-1.4.2}/base64/test/test_base64.c +0 -0
  92. {pybase64-1.4.1 → pybase64-1.4.2}/setup.cfg +0 -0
  93. {pybase64-1.4.1 → pybase64-1.4.2}/src/pybase64/__init__.py +0 -0
  94. {pybase64-1.4.1 → pybase64-1.4.2}/src/pybase64/_fallback.py +0 -0
  95. {pybase64-1.4.1 → pybase64-1.4.2}/src/pybase64/_license.py +0 -0
  96. {pybase64-1.4.1 → pybase64-1.4.2}/src/pybase64/_license.pyi +0 -0
  97. {pybase64-1.4.1 → pybase64-1.4.2}/src/pybase64/_pybase64.c +0 -0
  98. {pybase64-1.4.1 → pybase64-1.4.2}/src/pybase64/_pybase64.pyi +0 -0
  99. {pybase64-1.4.1 → pybase64-1.4.2}/src/pybase64/_pybase64_get_simd_flags.c +0 -0
  100. {pybase64-1.4.1 → pybase64-1.4.2}/src/pybase64/_pybase64_get_simd_flags.h +0 -0
  101. {pybase64-1.4.1 → pybase64-1.4.2}/src/pybase64/_typing.py +0 -0
  102. {pybase64-1.4.1 → pybase64-1.4.2}/src/pybase64/py.typed +0 -0
  103. {pybase64-1.4.1 → pybase64-1.4.2}/src/pybase64.egg-info/SOURCES.txt +0 -0
  104. {pybase64-1.4.1 → pybase64-1.4.2}/src/pybase64.egg-info/dependency_links.txt +0 -0
  105. {pybase64-1.4.1 → pybase64-1.4.2}/src/pybase64.egg-info/entry_points.txt +0 -0
  106. {pybase64-1.4.1 → pybase64-1.4.2}/src/pybase64.egg-info/top_level.txt +0 -0
  107. {pybase64-1.4.1 → pybase64-1.4.2}/tests/test_benchmark.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: pybase64
3
- Version: 1.4.1
3
+ Version: 1.4.2
4
4
  Summary: Fast Base64 encoding/decoding
5
5
  Home-page: https://github.com/mayeut/pybase64
6
6
  Author: Matthieu Darbois
@@ -22,6 +22,7 @@ Classifier: Programming Language :: Python :: 3.10
22
22
  Classifier: Programming Language :: Python :: 3.11
23
23
  Classifier: Programming Language :: Python :: 3.12
24
24
  Classifier: Programming Language :: Python :: 3.13
25
+ Classifier: Programming Language :: Python :: 3.14
25
26
  Requires-Python: >=3.8
26
27
  Description-Content-Type: text/x-rst
27
28
  License-File: LICENSE
@@ -32,6 +33,7 @@ Dynamic: description-content-type
32
33
  Dynamic: home-page
33
34
  Dynamic: keywords
34
35
  Dynamic: license
36
+ Dynamic: license-file
35
37
  Dynamic: project-url
36
38
  Dynamic: requires-python
37
39
  Dynamic: summary
@@ -159,6 +161,15 @@ Running Python 3.7.2, Apple LLVM version 10.0.0 (clang-1000.11.45.5), Mac OS X 1
159
161
 
160
162
  Changelog
161
163
  =========
164
+ 1.4.2
165
+ -----
166
+ - Update base64 library (Windows ARM64 Neon support)
167
+ - Publish Python 3.14 wheels
168
+ - Publish Linux riscv64 wheels
169
+ - Publish Android wheels
170
+ - Publish iOS wheels
171
+ - Publish GraalPy wheels
172
+
162
173
  1.4.1
163
174
  -----
164
175
  - Publish PyPy 3.11 wheels
@@ -121,6 +121,15 @@ Running Python 3.7.2, Apple LLVM version 10.0.0 (clang-1000.11.45.5), Mac OS X 1
121
121
 
122
122
  Changelog
123
123
  =========
124
+ 1.4.2
125
+ -----
126
+ - Update base64 library (Windows ARM64 Neon support)
127
+ - Publish Python 3.14 wheels
128
+ - Publish Linux riscv64 wheels
129
+ - Publish Android wheels
130
+ - Publish iOS wheels
131
+ - Publish GraalPy wheels
132
+
124
133
  1.4.1
125
134
  -----
126
135
  - Publish PyPy 3.11 wheels
@@ -62,6 +62,8 @@ jobs:
62
62
  platform: "arm64"
63
63
  - runner: "ubuntu-22.04-arm"
64
64
  platform: "aarch64"
65
+ - runner: "windows-11-arm"
66
+ platform: "ARM64"
65
67
  steps:
66
68
  - name: Checkout
67
69
  uses: actions/checkout@v4
@@ -141,7 +143,7 @@ jobs:
141
143
  steps:
142
144
  - name: Checkout
143
145
  uses: actions/checkout@v4
144
- - uses: uraimo/run-on-arch-action@v2
146
+ - uses: uraimo/run-on-arch-action@v3
145
147
  with:
146
148
  arch: ${{matrix.arch}}
147
149
  distro: alpine_latest
@@ -162,7 +164,7 @@ jobs:
162
164
  steps:
163
165
  - name: Checkout
164
166
  uses: actions/checkout@v4
165
- - uses: uraimo/run-on-arch-action@v2
167
+ - uses: uraimo/run-on-arch-action@v3
166
168
  with:
167
169
  arch: ${{matrix.arch}}
168
170
  distro: alpine_latest
@@ -12,7 +12,8 @@
12
12
  ////////////////////////////////////////////////////////////////////////////////
13
13
 
14
14
  // ARM 64-Bit
15
- #if defined(__aarch64__)
15
+ #if defined(__aarch64__) \
16
+ || defined(_M_ARM64)
16
17
  #error ##arch=arm64##
17
18
 
18
19
  // ARM 32-Bit
@@ -8,13 +8,7 @@
8
8
  #include "config.h"
9
9
  #include "../../env.h"
10
10
 
11
- #ifdef __aarch64__
12
- # if (defined(__ARM_NEON__) || defined(__ARM_NEON)) && HAVE_NEON64
13
- # define BASE64_USE_NEON64
14
- # endif
15
- #endif
16
-
17
- #ifdef BASE64_USE_NEON64
11
+ #if HAVE_NEON64
18
12
  #include <arm_neon.h>
19
13
 
20
14
  // Only enable inline assembly on supported compilers.
@@ -66,7 +60,7 @@ load_64byte_table (const uint8_t *p)
66
60
  # include "enc_loop.c"
67
61
  #endif
68
62
 
69
- #endif // BASE64_USE_NEON64
63
+ #endif // HAVE_NEON64
70
64
 
71
65
  // Stride size is so large on these NEON 64-bit functions
72
66
  // (48 bytes encode, 64 bytes decode) that we inline the
@@ -75,7 +69,7 @@ load_64byte_table (const uint8_t *p)
75
69
  void
76
70
  base64_stream_encode_neon64 BASE64_ENC_PARAMS
77
71
  {
78
- #ifdef BASE64_USE_NEON64
72
+ #if HAVE_NEON64
79
73
  #include "../generic/enc_head.c"
80
74
  enc_loop_neon64(&s, &slen, &o, &olen);
81
75
  enc_loop_generic_64(&s, &slen, &o, &olen);
@@ -88,7 +82,7 @@ base64_stream_encode_neon64 BASE64_ENC_PARAMS
88
82
  int
89
83
  base64_stream_decode_neon64 BASE64_DEC_PARAMS
90
84
  {
91
- #ifdef BASE64_USE_NEON64
85
+ #if HAVE_NEON64
92
86
  #include "../generic/dec_head.c"
93
87
  dec_loop_neon64(&s, &slen, &o, &olen);
94
88
  dec_loop_generic_32(&s, &slen, &o, &olen);
@@ -100,10 +100,10 @@ dec_loop_neon64 (const uint8_t **s, size_t *slen, uint8_t **o, size_t *olen)
100
100
 
101
101
  // Check for invalid input, any value larger than 63:
102
102
  const uint8x16_t classified
103
- = vcgtq_u8(str.val[0], vdupq_n_u8(63))
104
- | vcgtq_u8(str.val[1], vdupq_n_u8(63))
105
- | vcgtq_u8(str.val[2], vdupq_n_u8(63))
106
- | vcgtq_u8(str.val[3], vdupq_n_u8(63));
103
+ = vorrq_u8(
104
+ vorrq_u8(vcgtq_u8(str.val[0], vdupq_n_u8(63)), vcgtq_u8(str.val[1], vdupq_n_u8(63))),
105
+ vorrq_u8(vcgtq_u8(str.val[2], vdupq_n_u8(63)), vcgtq_u8(str.val[3], vdupq_n_u8(63)))
106
+ );
107
107
 
108
108
  // Check that all bits are zero:
109
109
  if (vmaxvq_u8(classified) != 0U) {
@@ -111,9 +111,9 @@ dec_loop_neon64 (const uint8_t **s, size_t *slen, uint8_t **o, size_t *olen)
111
111
  }
112
112
 
113
113
  // Compress four bytes into three:
114
- dec.val[0] = vshlq_n_u8(str.val[0], 2) | vshrq_n_u8(str.val[1], 4);
115
- dec.val[1] = vshlq_n_u8(str.val[1], 4) | vshrq_n_u8(str.val[2], 2);
116
- dec.val[2] = vshlq_n_u8(str.val[2], 6) | str.val[3];
114
+ dec.val[0] = vorrq_u8(vshlq_n_u8(str.val[0], 2), vshrq_n_u8(str.val[1], 4));
115
+ dec.val[1] = vorrq_u8(vshlq_n_u8(str.val[1], 4), vshrq_n_u8(str.val[2], 2));
116
+ dec.val[2] = vorrq_u8(vshlq_n_u8(str.val[2], 6), str.val[3]);
117
117
 
118
118
  // Interleave and store decoded result:
119
119
  vst3q_u8((uint8_t *) *o, dec);
@@ -163,13 +163,13 @@ codec_choose_forced (struct codec *codec, int flags)
163
163
  static bool
164
164
  codec_choose_arm (struct codec *codec)
165
165
  {
166
- #if (defined(__ARM_NEON__) || defined(__ARM_NEON)) && ((defined(__aarch64__) && HAVE_NEON64) || HAVE_NEON32)
166
+ #if HAVE_NEON64 || ((defined(__ARM_NEON__) || defined(__ARM_NEON)) && HAVE_NEON32)
167
167
 
168
168
  // Unfortunately there is no portable way to check for NEON
169
169
  // support at runtime from userland in the same way that x86
170
170
  // has cpuid, so just stick to the compile-time configuration:
171
171
 
172
- #if defined(__aarch64__) && HAVE_NEON64
172
+ #if HAVE_NEON64
173
173
  codec->enc = base64_stream_encode_neon64;
174
174
  codec->dec = base64_stream_decode_neon64;
175
175
  #else
@@ -3,24 +3,22 @@ requires = ["setuptools"]
3
3
  build-backend = "setuptools.build_meta"
4
4
 
5
5
  [tool.cibuildwheel]
6
- enable = ["cpython-freethreading", "pypy"]
7
- test-requires = "-r requirements-test.txt"
8
- test-command = "pytest {project}/tests"
9
- test-skip = "*-win_arm64" # silence warnings for windows ARM64
10
6
  build-verbosity = 1
11
- manylinux-i686-image = "manylinux2014"
12
- manylinux-pypy_i686-image = "manylinux2014"
13
- manylinux-x86_64-image = "manylinux_2_28"
14
- manylinux-pypy_x86_64-image = "manylinux_2_28"
15
- manylinux-aarch64-image = "manylinux_2_28"
16
- manylinux-pypy_aarch64-image = "manylinux_2_28"
17
- manylinux-ppc64le-image = "manylinux_2_28"
18
- manylinux-s390x-image = "manylinux_2_28"
7
+ enable = ["cpython-experimental-riscv64", "cpython-freethreading", "graalpy", "pypy", "pypy-eol"]
8
+ test-skip = ["gp311_242-win_amd64"] # https://github.com/oracle/graalpython/issues/490
9
+ test-requires = "-r requirements-test.txt"
10
+ test-sources = ["conftest.py", "pyproject.toml", "tests"]
11
+ test-command = "python -m pytest"
12
+ xbuild-tools = ["cmake"]
19
13
 
20
14
  [[tool.cibuildwheel.overrides]]
21
15
  select = "*-manylinux*"
22
16
  environment = { AUDITWHEEL_PLAT="manylinux2014_${AUDITWHEEL_ARCH}" }
23
17
 
18
+ [[tool.cibuildwheel.overrides]]
19
+ select = "*-manylinux_riscv64"
20
+ environment = { AUDITWHEEL_PLAT="manylinux_2_31_${AUDITWHEEL_ARCH}" }
21
+
24
22
  [tool.coverage.run]
25
23
  branch = true
26
24
  omit = [
@@ -72,6 +72,7 @@ def get_cmake_extra_config(plat_name: str | None, build_type: str) -> tuple[bool
72
72
  log.info(" CC: %s", os.environ.get("CC", None))
73
73
  log.info(" CFLAGS: %s", os.environ.get("CFLAGS", None))
74
74
  log.info(" LDFLAGS: %s", os.environ.get("LDFLAGS", None))
75
+ log.info(" CMAKE_TOOLCHAIN_FILE: %s", os.environ.get("CMAKE_TOOLCHAIN_FILE", None))
75
76
  log.info(" sysconfig CC: %s", sysconfig.get_config_var("CC"))
76
77
  log.info(" sysconfig CCSHARED: %s", sysconfig.get_config_var("CCSHARED"))
77
78
  log.info(" sysconfig CFLAGS: %s", sysconfig.get_config_var("CFLAGS"))
@@ -81,6 +82,8 @@ def get_cmake_extra_config(plat_name: str | None, build_type: str) -> tuple[bool
81
82
 
82
83
  platform = plat_name or platform
83
84
  is_msvc = platform.startswith("win")
85
+ is_macos = platform.startswith("macosx-")
86
+ is_ios = platform.startswith("ios-")
84
87
 
85
88
  if not is_msvc:
86
89
  extra_config.append(f"-DCMAKE_BUILD_TYPE={build_type}")
@@ -97,7 +100,7 @@ def get_cmake_extra_config(plat_name: str | None, build_type: str) -> tuple[bool
97
100
  extra_config.append("-A Win32")
98
101
  if platform == "win-arm64" and machine != "arm64":
99
102
  extra_config.append("-A ARM64")
100
- elif IS_MACOS:
103
+ elif is_macos or is_ios:
101
104
  known_archs = {
102
105
  "arm64",
103
106
  "arm64e",
@@ -108,10 +111,18 @@ def get_cmake_extra_config(plat_name: str | None, build_type: str) -> tuple[bool
108
111
  "ppc",
109
112
  "ppc64",
110
113
  }
111
- if not platform.startswith("macosx-"):
112
- msg = f"Building {platform} is not supported on macOS"
114
+ if is_macos and not IS_MACOS:
115
+ msg = f"Building {platform} is only supported on macOS"
113
116
  raise ValueError(msg)
114
- _, _, platform_arch = platform.split("-")
117
+ if is_ios:
118
+ _, min_ver, platform_arch, sdk = platform.split("-")
119
+ min_ver = os.getenv("IPHONEOS_DEPLOYMENT_TARGET", min_ver)
120
+ extra_config.append("-DCMAKE_SYSTEM_NAME=iOS")
121
+ extra_config.append(f"-DCMAKE_OSX_SYSROOT={sdk}")
122
+ else:
123
+ _, min_ver, platform_arch = platform.split("-")
124
+ min_ver = os.getenv("MACOSX_DEPLOYMENT_TARGET", min_ver)
125
+ extra_config.append(f"-DCMAKE_OSX_DEPLOYMENT_TARGET={min_ver}")
115
126
  if platform_arch.startswith(("universal", "fat")):
116
127
  msg = f"multiple arch `{platform_arch}` is not supported"
117
128
  raise ValueError(msg)
@@ -153,6 +164,7 @@ def base64_build(plat_name: str | None) -> Generator[bool, None, None]:
153
164
  "-DBASE64_BUILD_TESTS:BOOL=OFF",
154
165
  "-DBASE64_BUILD_CLI:BOOL=OFF",
155
166
  "-DCMAKE_POSITION_INDEPENDENT_CODE=ON",
167
+ "-DBUILD_SHARED_LIBS:BOOL=OFF",
156
168
  ]
157
169
  if build_dir.exists():
158
170
  shutil.rmtree(build_dir)
@@ -243,6 +255,7 @@ setup(
243
255
  "Programming Language :: Python :: 3.11",
244
256
  "Programming Language :: Python :: 3.12",
245
257
  "Programming Language :: Python :: 3.13",
258
+ "Programming Language :: Python :: 3.14",
246
259
  ],
247
260
  # Supported python versions
248
261
  python_requires=">=3.8",
@@ -6,8 +6,9 @@ import sys
6
6
  from base64 import b64decode as b64decodeValidate
7
7
  from base64 import encodebytes as b64encodebytes
8
8
  from collections.abc import Sequence
9
+ from pathlib import Path
9
10
  from timeit import default_timer as timer
10
- from typing import TYPE_CHECKING, Any, BinaryIO, cast
11
+ from typing import TYPE_CHECKING, Any
11
12
 
12
13
  import pybase64
13
14
 
@@ -95,38 +96,20 @@ def bench_one(
95
96
  assert decodedcontent == data
96
97
 
97
98
 
98
- def readall(file: BinaryIO) -> bytes:
99
- if sys.version_info[:2] == (3, 8) and file == cast(BinaryIO, sys.stdin): # pragma: no cover
100
- # Python 3 < 3.9 does not honor the binary flag,
101
- # read from the underlying buffer
102
- if hasattr(file, "buffer"):
103
- return cast(BinaryIO, file.buffer).read()
104
- return file.read()
105
- # do not close the file
106
- try:
107
- data = file.read()
108
- finally:
109
- file.close()
110
- return data
99
+ def readall(file: str) -> bytes:
100
+ if file == "-":
101
+ return sys.stdin.buffer.read()
102
+ return Path(file).read_bytes()
111
103
 
112
104
 
113
- def writeall(file: BinaryIO, data: bytes) -> None:
114
- if file == cast(BinaryIO, sys.stdout):
115
- # Python 3 does not honor the binary flag,
116
- # write to the underlying buffer
117
- if hasattr(file, "buffer"):
118
- file.buffer.write(data)
119
- else:
120
- file.write(data) # pragma: no cover
121
- # do not close the file
105
+ def writeall(file: str, data: bytes) -> None:
106
+ if file == "-":
107
+ sys.stdout.buffer.write(data)
122
108
  else:
123
- try:
124
- file.write(data)
125
- finally:
126
- file.close()
109
+ Path(file).write_bytes(data)
127
110
 
128
111
 
129
- def benchmark(duration: float, input: BinaryIO) -> None:
112
+ def benchmark(duration: float, input: str) -> None:
130
113
  print(__package__ + " " + pybase64.get_version())
131
114
  data = readall(input)
132
115
  for altchars in [None, b"-_"]:
@@ -152,13 +135,13 @@ def benchmark(duration: float, input: BinaryIO) -> None:
152
135
  )
153
136
 
154
137
 
155
- def encode(input: BinaryIO, altchars: bytes | None, output: BinaryIO) -> None:
138
+ def encode(input: str, altchars: bytes | None, output: str) -> None:
156
139
  data = readall(input)
157
140
  data = pybase64.b64encode(data, altchars)
158
141
  writeall(output, data)
159
142
 
160
143
 
161
- def decode(input: BinaryIO, altchars: bytes | None, validate: bool, output: BinaryIO) -> None:
144
+ def decode(input: str, altchars: bytes | None, validate: bool, output: str) -> None:
162
145
  data = readall(input)
163
146
  data = pybase64.b64decode(data, altchars, validate)
164
147
  writeall(output, data)
@@ -192,6 +175,15 @@ class LicenseAction(argparse.Action):
192
175
  parser.exit()
193
176
 
194
177
 
178
+ def check_file(value: str, is_input: bool) -> str:
179
+ if value == "-":
180
+ return value
181
+ path = Path(value)
182
+ if is_input:
183
+ return str(path.resolve(strict=True))
184
+ return str(path.parent.resolve(strict=True) / path.name)
185
+
186
+
195
187
  def main(argv: Sequence[str] | None = None) -> None:
196
188
  # main parser
197
189
  parser = argparse.ArgumentParser(
@@ -217,15 +209,16 @@ def main(argv: Sequence[str] | None = None) -> None:
217
209
  default=1.0,
218
210
  help="expected duration for a single encode or decode test",
219
211
  )
212
+ benchmark_parser.register("type", "input file", lambda s: check_file(s, True))
220
213
  benchmark_parser.add_argument(
221
- "input", type=argparse.FileType("rb"), help="input file used for the benchmark"
214
+ "input", type="input file", help="input file used for the benchmark"
222
215
  )
223
216
  benchmark_parser.set_defaults(func=benchmark)
224
217
  # encode parser
225
218
  encode_parser = subparsers.add_parser("encode", help="-h for usage")
226
- encode_parser.add_argument(
227
- "input", type=argparse.FileType("rb"), help="input file to be encoded"
228
- )
219
+ encode_parser.register("type", "input file", lambda s: check_file(s, True))
220
+ encode_parser.register("type", "output file", lambda s: check_file(s, False))
221
+ encode_parser.add_argument("input", type="input file", help="input file to be encoded")
229
222
  group = encode_parser.add_mutually_exclusive_group()
230
223
  group.add_argument(
231
224
  "-u",
@@ -245,16 +238,16 @@ def main(argv: Sequence[str] | None = None) -> None:
245
238
  "-o",
246
239
  "--output",
247
240
  dest="output",
248
- type=argparse.FileType("wb"),
249
- default=sys.stdout,
241
+ type="output file",
242
+ default="-",
250
243
  help="encoded output file (default to stdout)",
251
244
  )
252
245
  encode_parser.set_defaults(func=encode)
253
246
  # decode parser
254
247
  decode_parser = subparsers.add_parser("decode", help="-h for usage")
255
- decode_parser.add_argument(
256
- "input", type=argparse.FileType("rb"), help="input file to be decoded"
257
- )
248
+ decode_parser.register("type", "input file", lambda s: check_file(s, True))
249
+ decode_parser.register("type", "output file", lambda s: check_file(s, False))
250
+ decode_parser.add_argument("input", type="input file", help="input file to be decoded")
258
251
  group = decode_parser.add_mutually_exclusive_group()
259
252
  group.add_argument(
260
253
  "-u",
@@ -274,8 +267,8 @@ def main(argv: Sequence[str] | None = None) -> None:
274
267
  "-o",
275
268
  "--output",
276
269
  dest="output",
277
- type=argparse.FileType("wb"),
278
- default=sys.stdout,
270
+ type="output file",
271
+ default="-",
279
272
  help="decoded output file (default to stdout)",
280
273
  )
281
274
  decode_parser.add_argument(
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- _version = "1.4.1"
3
+ _version = "1.4.2"
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: pybase64
3
- Version: 1.4.1
3
+ Version: 1.4.2
4
4
  Summary: Fast Base64 encoding/decoding
5
5
  Home-page: https://github.com/mayeut/pybase64
6
6
  Author: Matthieu Darbois
@@ -22,6 +22,7 @@ Classifier: Programming Language :: Python :: 3.10
22
22
  Classifier: Programming Language :: Python :: 3.11
23
23
  Classifier: Programming Language :: Python :: 3.12
24
24
  Classifier: Programming Language :: Python :: 3.13
25
+ Classifier: Programming Language :: Python :: 3.14
25
26
  Requires-Python: >=3.8
26
27
  Description-Content-Type: text/x-rst
27
28
  License-File: LICENSE
@@ -32,6 +33,7 @@ Dynamic: description-content-type
32
33
  Dynamic: home-page
33
34
  Dynamic: keywords
34
35
  Dynamic: license
36
+ Dynamic: license-file
35
37
  Dynamic: project-url
36
38
  Dynamic: requires-python
37
39
  Dynamic: summary
@@ -159,6 +161,15 @@ Running Python 3.7.2, Apple LLVM version 10.0.0 (clang-1000.11.45.5), Mac OS X 1
159
161
 
160
162
  Changelog
161
163
  =========
164
+ 1.4.2
165
+ -----
166
+ - Update base64 library (Windows ARM64 Neon support)
167
+ - Publish Python 3.14 wheels
168
+ - Publish Linux riscv64 wheels
169
+ - Publish Android wheels
170
+ - Publish iOS wheels
171
+ - Publish GraalPy wheels
172
+
162
173
  1.4.1
163
174
  -----
164
175
  - Publish PyPy 3.11 wheels
@@ -138,8 +138,11 @@ def test_decode(
138
138
  assert captured.out == b"hello world !/?\n"
139
139
 
140
140
 
141
+ @pytest.mark.skipif(
142
+ sys.platform.startswith(("android", "emscripten", "ios")), reason="subprocess not supported"
143
+ )
141
144
  def test_subprocess() -> None:
142
- import subprocess
145
+ import subprocess # noqa: PLC0415
143
146
 
144
147
  process = subprocess.Popen(
145
148
  [sys.executable, "-m", "pybase64", "encode", "-"],
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import base64
4
+ import sys
4
5
  from base64 import encodebytes as b64encodebytes
5
6
  from binascii import Error as BinAsciiError
6
7
  from collections.abc import Callable
@@ -384,6 +385,8 @@ def test_invalid_data_dec_skip(
384
385
  ) -> None:
385
386
  utils.unused_args(exception, simd) # simd is a parameter in order to control the order of tests
386
387
  test = dfn(vector, altchars)
388
+ if sys.implementation.name == "graalpy" and vector.startswith((b"A@@@=F", b"A@@=@")):
389
+ pytest.xfail(reason="graalpy fails decoding those entries") # pragma: no cover
387
390
  base = base64.b64decode(vector, altchars)
388
391
  assert test == base
389
392
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes