pyicu 2.15.2__tar.gz → 2.16__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 (112) hide show
  1. {pyicu-2.15.2 → pyicu-2.16}/CHANGES +17 -0
  2. {pyicu-2.15.2 → pyicu-2.16}/CREDITS +2 -1
  3. {pyicu-2.15.2/py/PyICU.egg-info → pyicu-2.16}/PKG-INFO +1 -1
  4. {pyicu-2.15.2 → pyicu-2.16}/arg.h +5 -4
  5. {pyicu-2.15.2 → pyicu-2.16}/bidi.cpp +15 -30
  6. {pyicu-2.15.2 → pyicu-2.16}/char.cpp +36 -2
  7. {pyicu-2.15.2 → pyicu-2.16}/collator.cpp +24 -14
  8. {pyicu-2.15.2 → pyicu-2.16}/common.cpp +0 -29
  9. {pyicu-2.15.2 → pyicu-2.16}/common.h +36 -1
  10. {pyicu-2.15.2 → pyicu-2.16}/format.cpp +2 -2
  11. {pyicu-2.15.2 → pyicu-2.16}/iterators.cpp +3 -11
  12. {pyicu-2.15.2 → pyicu-2.16}/locale.cpp +32 -45
  13. {pyicu-2.15.2 → pyicu-2.16}/measureunit.cpp +26 -4
  14. {pyicu-2.15.2 → pyicu-2.16/py/PyICU.egg-info}/PKG-INFO +1 -1
  15. {pyicu-2.15.2 → pyicu-2.16}/script.cpp +7 -0
  16. {pyicu-2.15.2 → pyicu-2.16}/setup.py +2 -2
  17. {pyicu-2.15.2 → pyicu-2.16}/timezone.cpp +3 -11
  18. {pyicu-2.15.2 → pyicu-2.16}/LICENSE +0 -0
  19. {pyicu-2.15.2 → pyicu-2.16}/MANIFEST.in +0 -0
  20. {pyicu-2.15.2 → pyicu-2.16}/README.md +0 -0
  21. {pyicu-2.15.2 → pyicu-2.16}/_icu_.cpp +0 -0
  22. {pyicu-2.15.2 → pyicu-2.16}/bases.cpp +0 -0
  23. {pyicu-2.15.2 → pyicu-2.16}/bases.h +0 -0
  24. {pyicu-2.15.2 → pyicu-2.16}/bidi.h +0 -0
  25. {pyicu-2.15.2 → pyicu-2.16}/calendar.cpp +0 -0
  26. {pyicu-2.15.2 → pyicu-2.16}/calendar.h +0 -0
  27. {pyicu-2.15.2 → pyicu-2.16}/casemap.cpp +0 -0
  28. {pyicu-2.15.2 → pyicu-2.16}/casemap.h +0 -0
  29. {pyicu-2.15.2 → pyicu-2.16}/char.h +0 -0
  30. {pyicu-2.15.2 → pyicu-2.16}/charset.cpp +0 -0
  31. {pyicu-2.15.2 → pyicu-2.16}/charset.h +0 -0
  32. {pyicu-2.15.2 → pyicu-2.16}/collator.h +0 -0
  33. {pyicu-2.15.2 → pyicu-2.16}/dateformat.cpp +0 -0
  34. {pyicu-2.15.2 → pyicu-2.16}/dateformat.h +0 -0
  35. {pyicu-2.15.2 → pyicu-2.16}/displayoptions.cpp +0 -0
  36. {pyicu-2.15.2 → pyicu-2.16}/displayoptions.h +0 -0
  37. {pyicu-2.15.2 → pyicu-2.16}/errors.cpp +0 -0
  38. {pyicu-2.15.2 → pyicu-2.16}/errors.h +0 -0
  39. {pyicu-2.15.2 → pyicu-2.16}/format.h +0 -0
  40. {pyicu-2.15.2 → pyicu-2.16}/gender.cpp +0 -0
  41. {pyicu-2.15.2 → pyicu-2.16}/gender.h +0 -0
  42. {pyicu-2.15.2 → pyicu-2.16}/idna.cpp +0 -0
  43. {pyicu-2.15.2 → pyicu-2.16}/idna.h +0 -0
  44. {pyicu-2.15.2 → pyicu-2.16}/iterators.h +0 -0
  45. {pyicu-2.15.2 → pyicu-2.16}/layoutengine.cpp +0 -0
  46. {pyicu-2.15.2 → pyicu-2.16}/layoutengine.h +0 -0
  47. {pyicu-2.15.2 → pyicu-2.16}/locale.h +0 -0
  48. {pyicu-2.15.2 → pyicu-2.16}/macros.h +0 -0
  49. {pyicu-2.15.2 → pyicu-2.16}/measureunit.h +0 -0
  50. {pyicu-2.15.2 → pyicu-2.16}/messagepattern.cpp +0 -0
  51. {pyicu-2.15.2 → pyicu-2.16}/messagepattern.h +0 -0
  52. {pyicu-2.15.2 → pyicu-2.16}/normalizer.cpp +0 -0
  53. {pyicu-2.15.2 → pyicu-2.16}/normalizer.h +0 -0
  54. {pyicu-2.15.2 → pyicu-2.16}/numberformat.cpp +0 -0
  55. {pyicu-2.15.2 → pyicu-2.16}/numberformat.h +0 -0
  56. {pyicu-2.15.2 → pyicu-2.16}/py/PyICU.egg-info/SOURCES.txt +0 -0
  57. {pyicu-2.15.2 → pyicu-2.16}/py/PyICU.egg-info/dependency_links.txt +0 -0
  58. {pyicu-2.15.2 → pyicu-2.16}/py/PyICU.egg-info/top_level.txt +0 -0
  59. {pyicu-2.15.2 → pyicu-2.16}/py/icu/__init__.py +0 -0
  60. {pyicu-2.15.2 → pyicu-2.16}/pyproject.toml +0 -0
  61. {pyicu-2.15.2 → pyicu-2.16}/regex.cpp +0 -0
  62. {pyicu-2.15.2 → pyicu-2.16}/regex.h +0 -0
  63. {pyicu-2.15.2 → pyicu-2.16}/samples/break.py +0 -0
  64. {pyicu-2.15.2 → pyicu-2.16}/samples/strsrch.py +0 -0
  65. {pyicu-2.15.2 → pyicu-2.16}/script.h +0 -0
  66. {pyicu-2.15.2 → pyicu-2.16}/search.cpp +0 -0
  67. {pyicu-2.15.2 → pyicu-2.16}/search.h +0 -0
  68. {pyicu-2.15.2 → pyicu-2.16}/setup.cfg +0 -0
  69. {pyicu-2.15.2 → pyicu-2.16}/shape.cpp +0 -0
  70. {pyicu-2.15.2 → pyicu-2.16}/shape.h +0 -0
  71. {pyicu-2.15.2 → pyicu-2.16}/spoof.cpp +0 -0
  72. {pyicu-2.15.2 → pyicu-2.16}/spoof.h +0 -0
  73. {pyicu-2.15.2 → pyicu-2.16}/test/__init__.py +0 -0
  74. {pyicu-2.15.2 → pyicu-2.16}/test/lohit_hi.ttf +0 -0
  75. {pyicu-2.15.2 → pyicu-2.16}/test/noms.txt +0 -0
  76. {pyicu-2.15.2 → pyicu-2.16}/test/test_Bidi.py +0 -0
  77. {pyicu-2.15.2 → pyicu-2.16}/test/test_BreakIterator.py +0 -0
  78. {pyicu-2.15.2 → pyicu-2.16}/test/test_BytesTrie.py +0 -0
  79. {pyicu-2.15.2 → pyicu-2.16}/test/test_Charset.py +0 -0
  80. {pyicu-2.15.2 → pyicu-2.16}/test/test_Collator.py +0 -0
  81. {pyicu-2.15.2 → pyicu-2.16}/test/test_DateTimePatternGenerator.py +0 -0
  82. {pyicu-2.15.2 → pyicu-2.16}/test/test_LayoutEngine.py +0 -0
  83. {pyicu-2.15.2 → pyicu-2.16}/test/test_ListFormatter.py +0 -0
  84. {pyicu-2.15.2 → pyicu-2.16}/test/test_Locale.py +0 -0
  85. {pyicu-2.15.2 → pyicu-2.16}/test/test_LocaleData.py +0 -0
  86. {pyicu-2.15.2 → pyicu-2.16}/test/test_LocaleMatcher.py +0 -0
  87. {pyicu-2.15.2 → pyicu-2.16}/test/test_MessageFormat.py +0 -0
  88. {pyicu-2.15.2 → pyicu-2.16}/test/test_MessagePattern.py +0 -0
  89. {pyicu-2.15.2 → pyicu-2.16}/test/test_Normalizer.py +0 -0
  90. {pyicu-2.15.2 → pyicu-2.16}/test/test_NumberFormat.py +0 -0
  91. {pyicu-2.15.2 → pyicu-2.16}/test/test_NumberFormatter.py +0 -0
  92. {pyicu-2.15.2 → pyicu-2.16}/test/test_Property.py +0 -0
  93. {pyicu-2.15.2 → pyicu-2.16}/test/test_PythonReplaceable.py +0 -0
  94. {pyicu-2.15.2 → pyicu-2.16}/test/test_Regex.py +0 -0
  95. {pyicu-2.15.2 → pyicu-2.16}/test/test_Script.py +0 -0
  96. {pyicu-2.15.2 → pyicu-2.16}/test/test_SimpleFormatter.py +0 -0
  97. {pyicu-2.15.2 → pyicu-2.16}/test/test_Spoof.py +0 -0
  98. {pyicu-2.15.2 → pyicu-2.16}/test/test_TimeZone.py +0 -0
  99. {pyicu-2.15.2 → pyicu-2.16}/test/test_Transliterator.py +0 -0
  100. {pyicu-2.15.2 → pyicu-2.16}/test/test_UCS4.py +0 -0
  101. {pyicu-2.15.2 → pyicu-2.16}/test/test_UCharsTrie.py +0 -0
  102. {pyicu-2.15.2 → pyicu-2.16}/test/test_UDate.py +0 -0
  103. {pyicu-2.15.2 → pyicu-2.16}/test/test_UnicodeSet.py +0 -0
  104. {pyicu-2.15.2 → pyicu-2.16}/timezone.h +0 -0
  105. {pyicu-2.15.2 → pyicu-2.16}/transliterator.cpp +0 -0
  106. {pyicu-2.15.2 → pyicu-2.16}/transliterator.h +0 -0
  107. {pyicu-2.15.2 → pyicu-2.16}/tries.cpp +0 -0
  108. {pyicu-2.15.2 → pyicu-2.16}/tries.h +0 -0
  109. {pyicu-2.15.2 → pyicu-2.16}/tzinfo.cpp +0 -0
  110. {pyicu-2.15.2 → pyicu-2.16}/tzinfo.h +0 -0
  111. {pyicu-2.15.2 → pyicu-2.16}/unicodeset.cpp +0 -0
  112. {pyicu-2.15.2 → pyicu-2.16}/unicodeset.h +0 -0
@@ -1,3 +1,20 @@
1
+ Issues can be seen at https://gitlab.pyicu.org/main/pyicu/-/issues/<num>
2
+
3
+ Version 2.15.3 -> 2.16
4
+ ----------------------
5
+ - fixed issue #178
6
+ - added new enums from new unicode release in UBlockCode, UScriptCode
7
+ - added missing wrappers for ECollationStrength and EComparisonResult
8
+ - added wrapper for UIndicConjunctBreak
9
+ - added support for ICU 78.1
10
+
11
+ Version 2.15.2 -> 2.15.3
12
+ ------------------------
13
+ - replaced all malloc/calloc/free with std::unique_ptr<T[]>
14
+ - fixed issue #173
15
+ - fixed issue #175
16
+ - fixed issue #176
17
+
1
18
  Version 2.15.1 -> 2.15.2
2
19
  ------------------------
3
20
  - fixed calloc/free mismatch with arg::Q() uses (Fredrik Roubert)
@@ -3,7 +3,7 @@ PyICU is a Python extension wrapping Unicode Consortium's ICU library and
3
3
  wouldn't be possible without the tireless efforts of the people and open source
4
4
  projects below.
5
5
 
6
- - the ICU developers: http://icu-project.org
6
+ - the ICU developers: http://icu.unicode.org
7
7
 
8
8
  - the Open Source Applications Foundation, for hosting the project at its
9
9
  inception, in 2004: http://www.osafoundation.org
@@ -19,6 +19,7 @@ projects below.
19
19
  - Markus Scherer for various bug fixes (see CHANGES)
20
20
  - Martin Hosken for bug fixes (see CHANGES)
21
21
  - Roman Kalukiewicz for MessagePattern
22
+ - Martin Jansche for argument parsing and validation with modern C++
22
23
  -
23
24
 
24
25
  Thank you all !
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyicu
3
- Version: 2.15.2
3
+ Version: 2.16
4
4
  Summary: Python extension wrapping the ICU C++ API
5
5
  Home-page: https://gitlab.pyicu.org/main/pyicu
6
6
  Author: Andi Vajda
@@ -24,6 +24,7 @@
24
24
  #ifndef _arg_h
25
25
  #define _arg_h
26
26
 
27
+ #include <memory>
27
28
  #include <type_traits>
28
29
 
29
30
  #include "common.h"
@@ -385,13 +386,13 @@ template <typename T> class ICUObjectArray {
385
386
  private:
386
387
  const classid id;
387
388
  PyTypeObject *const type;
388
- std::unique_ptr<T *, decltype(free) *> *const array;
389
+ std::unique_ptr<T *[]> *const array;
389
390
  size_t *const len;
390
391
 
391
392
  public:
392
393
  ICUObjectArray() = delete;
393
394
 
394
- explicit ICUObjectArray(classid param1, PyTypeObject *param2, std::unique_ptr<T *, decltype(free) *> *param3, size_t *param4) noexcept
395
+ explicit ICUObjectArray(classid param1, PyTypeObject *param2, std::unique_ptr<T *[]> *param3, size_t *param4) noexcept
395
396
  : id(param1), type(param2), array(param3), len(param4) {}
396
397
 
397
398
  int parse(PyObject *arg) const
@@ -409,7 +410,7 @@ public:
409
410
  return -1;
410
411
  }
411
412
 
412
- array->reset(reinterpret_cast<T **>(pl2cpa(arg, len, id, type)));
413
+ *array = pl2cpa<T>(arg, len, id, type);
413
414
  if (!array->get())
414
415
  return -1;
415
416
 
@@ -853,7 +854,7 @@ public:
853
854
  };
854
855
 
855
856
  #define _IS_POD(T) \
856
- static_assert(std::is_trivial<T>::value); \
857
+ static_assert(std::is_trivially_copyable<T>::value); \
857
858
  static_assert(std::is_standard_layout<T>::value)
858
859
 
859
860
  _IS_POD(AnyPythonObject);
@@ -672,17 +672,12 @@ static PyObject *t_bidi_getLogicalMap(t_bidi *self)
672
672
  else
673
673
  length = ubidi_getProcessedLength(self->object);
674
674
 
675
- int *indexMap = (int *) calloc(length, sizeof(int));
675
+ std::unique_ptr<int[]> indexMap(new int[length]);
676
676
 
677
- if (indexMap == NULL)
677
+ if (!indexMap.get())
678
678
  return PyErr_NoMemory();
679
679
 
680
- STATUS_CALL(
681
- {
682
- ubidi_getLogicalMap(self->object, indexMap, &status);
683
- if (U_FAILURE(status))
684
- free(indexMap);
685
- });
680
+ STATUS_CALL(ubidi_getLogicalMap(self->object, indexMap.get(), &status));
686
681
 
687
682
  PyObject *result = PyTuple_New(length);
688
683
 
@@ -691,7 +686,6 @@ static PyObject *t_bidi_getLogicalMap(t_bidi *self)
691
686
  for (int i = 0; i < length; ++i)
692
687
  PyTuple_SET_ITEM(result, i, PyInt_FromLong(indexMap[i]));
693
688
  }
694
- free(indexMap);
695
689
 
696
690
  return result;
697
691
  }
@@ -705,17 +699,12 @@ static PyObject *t_bidi_getVisualMap(t_bidi *self)
705
699
  else
706
700
  length = ubidi_getResultLength(self->object);
707
701
 
708
- int *indexMap = (int *) calloc(length, sizeof(int));
702
+ std::unique_ptr<int[]> indexMap(new int[length]);
709
703
 
710
- if (indexMap == NULL)
704
+ if (!indexMap.get())
711
705
  return PyErr_NoMemory();
712
706
 
713
- STATUS_CALL(
714
- {
715
- ubidi_getVisualMap(self->object, indexMap, &status);
716
- if (U_FAILURE(status))
717
- free(indexMap);
718
- });
707
+ STATUS_CALL(ubidi_getVisualMap(self->object, indexMap.get(), &status));
719
708
 
720
709
  PyObject *result = PyTuple_New(length);
721
710
 
@@ -724,7 +713,6 @@ static PyObject *t_bidi_getVisualMap(t_bidi *self)
724
713
  for (int i = 0; i < length; ++i)
725
714
  PyTuple_SET_ITEM(result, i, PyInt_FromLong(indexMap[i]));
726
715
  }
727
- free(indexMap);
728
716
 
729
717
  return result;
730
718
  }
@@ -736,12 +724,12 @@ static PyObject *t_bidi_reorderLogical(PyTypeObject *type, PyObject *arg)
736
724
 
737
725
  if (!parseArg(arg, arg::H(&levels, &length)))
738
726
  {
739
- int *indexMap = (int *) calloc(length, sizeof(int));
727
+ std::unique_ptr<int[]> indexMap(new int[length]);
740
728
 
741
- if (indexMap == NULL)
729
+ if (!indexMap.get())
742
730
  return PyErr_NoMemory();
743
731
 
744
- ubidi_reorderLogical((const UBiDiLevel *) levels.get(), length, indexMap);
732
+ ubidi_reorderLogical((const UBiDiLevel *) levels.get(), length, indexMap.get());
745
733
 
746
734
  PyObject *result = PyTuple_New(length);
747
735
 
@@ -750,7 +738,6 @@ static PyObject *t_bidi_reorderLogical(PyTypeObject *type, PyObject *arg)
750
738
  for (size_t i = 0; i < length; ++i)
751
739
  PyTuple_SET_ITEM(result, i, PyInt_FromLong(indexMap[i]));
752
740
  }
753
- free(indexMap);
754
741
 
755
742
  return result;
756
743
  }
@@ -765,12 +752,12 @@ static PyObject *t_bidi_reorderVisual(PyTypeObject *type, PyObject *arg)
765
752
 
766
753
  if (!parseArg(arg, arg::H(&levels, &length)))
767
754
  {
768
- int *indexMap = (int *) calloc(length, sizeof(int));
755
+ std::unique_ptr<int[]> indexMap(new int[length]);
769
756
 
770
- if (indexMap == NULL)
757
+ if (!indexMap.get())
771
758
  return PyErr_NoMemory();
772
759
 
773
- ubidi_reorderVisual((const UBiDiLevel *) levels.get(), length, indexMap);
760
+ ubidi_reorderVisual((const UBiDiLevel *) levels.get(), length, indexMap.get());
774
761
 
775
762
  PyObject *result = PyTuple_New(length);
776
763
 
@@ -779,7 +766,6 @@ static PyObject *t_bidi_reorderVisual(PyTypeObject *type, PyObject *arg)
779
766
  for (size_t i = 0; i < length; ++i)
780
767
  PyTuple_SET_ITEM(result, i, PyInt_FromLong(indexMap[i]));
781
768
  }
782
- free(indexMap);
783
769
 
784
770
  return result;
785
771
  }
@@ -801,12 +787,12 @@ static PyObject *t_bidi_invertMap(PyTypeObject *type, PyObject *arg)
801
787
  maxSrc = srcMap[i];
802
788
 
803
789
  int destLength = maxSrc + 1;
804
- int *destMap = (int *) calloc(destLength, sizeof(int));
790
+ std::unique_ptr<int[]> destMap(new int[destLength]);
805
791
 
806
- if (destMap == NULL)
792
+ if (!destMap.get())
807
793
  return PyErr_NoMemory();
808
794
 
809
- ubidi_invertMap((const int *) srcMap.get(), destMap, srcLength);
795
+ ubidi_invertMap((const int *) srcMap.get(), destMap.get(), srcLength);
810
796
 
811
797
  PyObject *result = PyTuple_New(destLength);
812
798
 
@@ -815,7 +801,6 @@ static PyObject *t_bidi_invertMap(PyTypeObject *type, PyObject *arg)
815
801
  for (int i = 0; i < destLength; ++i)
816
802
  PyTuple_SET_ITEM(result, i, PyInt_FromLong(destMap[i]));
817
803
  }
818
- free(destMap);
819
804
 
820
805
  return result;
821
806
  }
@@ -1,5 +1,5 @@
1
1
  /* ====================================================================
2
- * Copyright (c) 2004-2024 Open Source Applications Foundation.
2
+ * Copyright (c) 2004-2025 Open Source Applications Foundation.
3
3
  *
4
4
  * Permission is hereby granted, free of charge, to any person obtaining a
5
5
  * copy of this software and associated documentation files (the "Software"),
@@ -58,6 +58,9 @@ DECLARE_CONSTANTS_TYPE(UCPMapRangeOption)
58
58
  DECLARE_CONSTANTS_TYPE(UIdentifierType)
59
59
  DECLARE_CONSTANTS_TYPE(UIdentifierStatus)
60
60
  #endif
61
+ #if U_ICU_VERSION_HEX >= VERSION_HEX(76, 0, 0)
62
+ DECLARE_CONSTANTS_TYPE(UIndicConjunctBreak)
63
+ #endif
61
64
 
62
65
  /* Char */
63
66
 
@@ -1151,6 +1154,9 @@ void _init_char(PyObject *m)
1151
1154
  INSTALL_CONSTANTS_TYPE(UIdentifierType, m);
1152
1155
  INSTALL_CONSTANTS_TYPE(UIdentifierStatus, m);
1153
1156
  #endif
1157
+ #if U_ICU_VERSION_HEX >= VERSION_HEX(76, 0, 0)
1158
+ INSTALL_CONSTANTS_TYPE(UIndicConjunctBreak, m);
1159
+ #endif
1154
1160
 
1155
1161
  INSTALL_STRUCT(Char, m);
1156
1162
  #if U_ICU_VERSION_HEX >= VERSION_HEX(63, 0, 0)
@@ -1166,6 +1172,7 @@ void _init_char(PyObject *m)
1166
1172
  INSTALL_ENUM(UProperty, "BIDI_MIRRORED", UCHAR_BIDI_MIRRORED);
1167
1173
  INSTALL_ENUM(UProperty, "DASH", UCHAR_DASH);
1168
1174
  INSTALL_ENUM(UProperty, "DEFAULT_IGNORABLE_CODE_POINT", UCHAR_DEFAULT_IGNORABLE_CODE_POINT);
1175
+ INSTALL_ENUM(UProperty, "DEPRECATED", UCHAR_DEPRECATED);
1169
1176
  INSTALL_ENUM(UProperty, "DIACRITIC", UCHAR_DIACRITIC);
1170
1177
  INSTALL_ENUM(UProperty, "EXTENDER", UCHAR_EXTENDER);
1171
1178
  INSTALL_ENUM(UProperty, "FULL_COMPOSITION_EXCLUSION", UCHAR_FULL_COMPOSITION_EXCLUSION);
@@ -1305,7 +1312,11 @@ void _init_char(PyObject *m)
1305
1312
  INSTALL_ENUM(UProperty, "IDENTIFIER_STATUS", UCHAR_IDENTIFIER_STATUS);
1306
1313
  INSTALL_ENUM(UProperty, "IDENTIFIER_TYPE", UCHAR_IDENTIFIER_TYPE);
1307
1314
  #endif
1308
- INSTALL_ENUM(UProperty, "INVALID_CODE ", UCHAR_INVALID_CODE );
1315
+ #if U_ICU_VERSION_HEX >= VERSION_HEX(76, 0, 0)
1316
+ INSTALL_ENUM(UProperty, "INDIC_CONJUNCT_BREAK", UCHAR_INDIC_CONJUNCT_BREAK);
1317
+ INSTALL_ENUM(UProperty, "MODIFIER_COMBINING_MARK", UCHAR_MODIFIER_COMBINING_MARK);
1318
+ #endif
1319
+ INSTALL_ENUM(UProperty, "INVALID_CODE", UCHAR_INVALID_CODE);
1309
1320
 
1310
1321
  INSTALL_ENUM(UCharDirection, "LEFT_TO_RIGHT", U_LEFT_TO_RIGHT);
1311
1322
  INSTALL_ENUM(UCharDirection, "RIGHT_TO_LEFT", U_RIGHT_TO_LEFT);
@@ -1734,6 +1745,16 @@ void _init_char(PyObject *m)
1734
1745
  INSTALL_ENUM(UBlockCode, "SYMBOLS_FOR_LEGACY_COMPUTING_SUPPLEMENT", UBLOCK_SYMBOLS_FOR_LEGACY_COMPUTING_SUPPLEMENT);
1735
1746
  INSTALL_ENUM(UBlockCode, "TODHRI", UBLOCK_TODHRI);
1736
1747
  INSTALL_ENUM(UBlockCode, "TULU_TIGALARI", UBLOCK_TULU_TIGALARI);
1748
+ #endif
1749
+ #if U_ICU_VERSION_HEX >= VERSION_HEX(78, 0, 0)
1750
+ INSTALL_ENUM(UBlockCode, "BERIA_ERFE", UBLOCK_BERIA_ERFE);
1751
+ INSTALL_ENUM(UBlockCode, "CJK_UNIFIED_IDEOGRAPHS_EXTENSION_J", UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_J);
1752
+ INSTALL_ENUM(UBlockCode, "MISCELLANEOUS_SYMBOLS_SUPPLEMENT", UBLOCK_MISCELLANEOUS_SYMBOLS_SUPPLEMENT);
1753
+ INSTALL_ENUM(UBlockCode, "SHARADA_SUPPLEMENT", UBLOCK_SHARADA_SUPPLEMENT);
1754
+ INSTALL_ENUM(UBlockCode, "SIDETIC", UBLOCK_SIDETIC);
1755
+ INSTALL_ENUM(UBlockCode, "TAI_YO", UBLOCK_TAI_YO);
1756
+ INSTALL_ENUM(UBlockCode, "TANGUT_COMPONENTS_SUPPLEMENT", UBLOCK_TANGUT_COMPONENTS_SUPPLEMENT);
1757
+ INSTALL_ENUM(UBlockCode, "TOLONG_SIKI", UBLOCK_TOLONG_SIKI);
1737
1758
  #endif
1738
1759
  INSTALL_ENUM(UBlockCode, "INVALID_CODE", UBLOCK_INVALID_CODE);
1739
1760
 
@@ -1811,6 +1832,13 @@ void _init_char(PyObject *m)
1811
1832
  #if U_ICU_VERSION_HEX >= VERSION_HEX(76, 0, 0)
1812
1833
  INSTALL_ENUM(UIndicSyllabicCategory, "REORDERING_KILLER", U_INSC_REORDERING_KILLER);
1813
1834
  #endif
1835
+
1836
+ #if U_ICU_VERSION_HEX >= VERSION_HEX(76, 0, 0)
1837
+ INSTALL_ENUM(UIndicConjunctBreak, "CONSONANT", U_INCB_CONSONANT);
1838
+ INSTALL_ENUM(UIndicConjunctBreak, "EXTEND", U_INCB_EXTEND);
1839
+ INSTALL_ENUM(UIndicConjunctBreak, "LINKER", U_INCB_LINKER);
1840
+ INSTALL_ENUM(UIndicConjunctBreak, "NONE", U_INCB_NONE);
1841
+ #endif
1814
1842
 
1815
1843
  INSTALL_ENUM(UVerticalOrientation, "ROTATED", U_VO_ROTATED);
1816
1844
  INSTALL_ENUM(UVerticalOrientation, "TRANSFORMED_ROTATED", U_VO_TRANSFORMED_ROTATED);
@@ -1922,6 +1950,9 @@ void _init_char(PyObject *m)
1922
1950
  #if U_ICU_VERSION_HEX >= VERSION_HEX(76, 0, 0)
1923
1951
  INSTALL_ENUM(UJoiningGroup, "KASHMIRI_YEH", U_JG_KASHMIRI_YEH);
1924
1952
  #endif
1953
+ #if U_ICU_VERSION_HEX >= VERSION_HEX(78, 0, 0)
1954
+ INSTALL_ENUM(UJoiningGroup, "THIN_NOON", U_JG_THIN_NOON);
1955
+ #endif
1925
1956
 
1926
1957
  INSTALL_ENUM(ULineBreak, "INSEPARABLE", U_LB_INSEPARABLE);
1927
1958
  INSTALL_ENUM(ULineBreak, "NEXT_LINE", U_LB_NEXT_LINE);
@@ -1952,6 +1983,9 @@ void _init_char(PyObject *m)
1952
1983
  INSTALL_ENUM(ULineBreak, "VIRAMA_FINAL", U_LB_VIRAMA_FINAL);
1953
1984
  INSTALL_ENUM(ULineBreak, "VIRAMA", U_LB_VIRAMA);
1954
1985
  #endif
1986
+ #if U_ICU_VERSION_HEX >= VERSION_HEX(78, 0, 0)
1987
+ INSTALL_ENUM(ULineBreak, "UNAMBIGUOUS_HYPHEN", U_LB_UNAMBIGUOUS_HYPHEN);
1988
+ #endif
1955
1989
 
1956
1990
  INSTALL_ENUM(UGraphemeClusterBreak, "OTHER", U_GCB_OTHER);
1957
1991
  INSTALL_ENUM(UGraphemeClusterBreak, "CONTROL", U_GCB_CONTROL);
@@ -34,6 +34,8 @@
34
34
  #include "arg.h"
35
35
 
36
36
  DECLARE_CONSTANTS_TYPE(UCollationResult)
37
+ DECLARE_CONSTANTS_TYPE(ECollationStrength)
38
+ DECLARE_CONSTANTS_TYPE(EComparisonResult)
37
39
  DECLARE_CONSTANTS_TYPE(UCollAttribute)
38
40
  DECLARE_CONSTANTS_TYPE(UCollAttributeValue)
39
41
  #if U_ICU_VERSION_HEX >= 0x04080000
@@ -536,7 +538,7 @@ static PyObject *t_collator_getSortKey(t_collator *self, PyObject *args)
536
538
  UnicodeString *u;
537
539
  UnicodeString _u;
538
540
  int len, size;
539
- uint8_t *buf;
541
+ std::unique_ptr<uint8_t[]> buf;
540
542
  PyObject *key;
541
543
 
542
544
  switch (PyTuple_Size(args)) {
@@ -544,21 +546,18 @@ static PyObject *t_collator_getSortKey(t_collator *self, PyObject *args)
544
546
  if (!parseArgs(args, arg::S(&u, &_u)))
545
547
  {
546
548
  len = u->length() * 4 + 8;
547
- buf = (uint8_t *) malloc(len);
549
+ buf.reset(new uint8_t[len]);
548
550
  retry:
549
- if (buf == NULL)
551
+ if (!buf.get())
550
552
  return PyErr_NoMemory();
551
553
 
552
- size = self->object->getSortKey(*u, buf, len);
554
+ size = self->object->getSortKey(*u, buf.get(), len);
553
555
  if (size <= len)
554
- {
555
- key = PyBytes_FromStringAndSize((char *) buf, size);
556
- free(buf);
557
- }
556
+ key = PyBytes_FromStringAndSize((char *) buf.get(), size);
558
557
  else
559
558
  {
560
559
  len = size;
561
- buf = (uint8_t *) realloc(buf, len);
560
+ buf.reset(new uint8_t[len]);
562
561
  goto retry;
563
562
  }
564
563
 
@@ -568,13 +567,12 @@ static PyObject *t_collator_getSortKey(t_collator *self, PyObject *args)
568
567
  case 2:
569
568
  if (!parseArgs(args, arg::S(&u, &_u), arg::i(&len)))
570
569
  {
571
- buf = (uint8_t *) calloc(len, 1);
572
- if (buf == NULL)
570
+ buf.reset(new uint8_t[len]);
571
+ if (!buf.get())
573
572
  return PyErr_NoMemory();
574
573
 
575
- len = self->object->getSortKey(*u, buf, len);
576
- key = PyBytes_FromStringAndSize((char *) buf, len);
577
- free(buf);
574
+ len = self->object->getSortKey(*u, buf.get(), len);
575
+ key = PyBytes_FromStringAndSize((char *) buf.get(), len);
578
576
 
579
577
  return key;
580
578
  }
@@ -1413,6 +1411,8 @@ void _init_collator(PyObject *m)
1413
1411
  ImmutableIndexType_.tp_as_sequence = &t_immutableindex_as_sequence;
1414
1412
  #endif
1415
1413
  INSTALL_CONSTANTS_TYPE(UCollationResult, m);
1414
+ INSTALL_CONSTANTS_TYPE(ECollationStrength, m);
1415
+ INSTALL_CONSTANTS_TYPE(EComparisonResult, m);
1416
1416
  INSTALL_CONSTANTS_TYPE(UCollAttribute, m);
1417
1417
  INSTALL_CONSTANTS_TYPE(UCollAttributeValue, m);
1418
1418
  REGISTER_TYPE(CollationKey, m);
@@ -1430,6 +1430,16 @@ void _init_collator(PyObject *m)
1430
1430
  INSTALL_ENUM(UCollationResult, "EQUAL", UCOL_EQUAL);
1431
1431
  INSTALL_ENUM(UCollationResult, "GREATER", UCOL_GREATER);
1432
1432
 
1433
+ INSTALL_ENUM(ECollationStrength, "PRIMARY", UCOL_PRIMARY);
1434
+ INSTALL_ENUM(ECollationStrength, "SECONDARY", UCOL_SECONDARY);
1435
+ INSTALL_ENUM(ECollationStrength, "TERTIARY", UCOL_TERTIARY);
1436
+ INSTALL_ENUM(ECollationStrength, "QUATERNARY", UCOL_QUATERNARY);
1437
+ INSTALL_ENUM(ECollationStrength, "IDENTICAL", UCOL_IDENTICAL);
1438
+
1439
+ INSTALL_ENUM(EComparisonResult, "LESS", UCOL_LESS);
1440
+ INSTALL_ENUM(EComparisonResult, "EQUAL", UCOL_EQUAL);
1441
+ INSTALL_ENUM(EComparisonResult, "GREATER", UCOL_GREATER);
1442
+
1433
1443
  INSTALL_ENUM(UCollAttribute, "FRENCH_COLLATION", UCOL_FRENCH_COLLATION);
1434
1444
  INSTALL_ENUM(UCollAttribute, "ALTERNATE_HANDLING", UCOL_ALTERNATE_HANDLING);
1435
1445
  INSTALL_ENUM(UCollAttribute, "CASE_FIRST", UCOL_CASE_FIRST);
@@ -645,35 +645,6 @@ int isInstance(PyObject *arg, classid id, PyTypeObject *type)
645
645
  return 0;
646
646
  }
647
647
 
648
- UObject **pl2cpa(PyObject *arg, size_t *len, classid id, PyTypeObject *type)
649
- {
650
- if (PySequence_Check(arg))
651
- {
652
- *len = (int) PySequence_Size(arg);
653
- UObject **array = (UObject **) calloc(*len, sizeof(UObject *));
654
-
655
- for (size_t i = 0; i < *len; i++) {
656
- PyObject *obj = PySequence_GetItem(arg, i);
657
-
658
- if (isInstance(obj, id, type))
659
- {
660
- array[i] = ((t_uobject *) obj)->object;
661
- Py_DECREF(obj);
662
- }
663
- else
664
- {
665
- Py_DECREF(obj);
666
- free(array);
667
- return NULL;
668
- }
669
- }
670
-
671
- return array;
672
- }
673
-
674
- return NULL;
675
- }
676
-
677
648
  PyObject *cpa2pl(UObject **array, size_t len, PyObject *(*wrap)(UObject *, int))
678
649
  {
679
650
  PyObject *list = PyList_New(len);
@@ -449,7 +449,42 @@ Formattable *toFormattable(PyObject *arg);
449
449
  Formattable *toFormattableArray(PyObject *arg, size_t *len,
450
450
  classid id, PyTypeObject *type);
451
451
 
452
- UObject **pl2cpa(PyObject *arg, size_t *len, classid id, PyTypeObject *type);
452
+ #include "bases.h"
453
+
454
+ template <typename T>
455
+ std::unique_ptr<T *[]> pl2cpa(PyObject *arg, size_t *len, classid id, PyTypeObject *type)
456
+ {
457
+ std::unique_ptr<T *[]> array;
458
+
459
+ if (PySequence_Check(arg))
460
+ {
461
+ *len = (int) PySequence_Size(arg);
462
+ array.reset(new T *[*len]);
463
+ if (!array.get())
464
+ PyErr_NoMemory();
465
+ else
466
+ {
467
+ for (size_t i = 0; i < *len; i++) {
468
+ PyObject *obj = PySequence_GetItem(arg, i);
469
+
470
+ if (isInstance(obj, id, type))
471
+ {
472
+ array[i] = reinterpret_cast<T *>(((t_uobject *) obj)->object);
473
+ Py_DECREF(obj);
474
+ }
475
+ else
476
+ {
477
+ Py_DECREF(obj);
478
+ array.reset(nullptr);
479
+ break;
480
+ }
481
+ }
482
+ }
483
+ }
484
+
485
+ return array;
486
+ }
487
+
453
488
  PyObject *cpa2pl(UObject **array, size_t len, PyObject *(*wrap)(UObject *, int));
454
489
 
455
490
  int *toIntArray(PyObject *arg, size_t *len);
@@ -964,7 +964,7 @@ static PyObject *t_measureformat_formatMeasure(t_measureformat *self,
964
964
  static PyObject *t_measureformat_formatMeasures(t_measureformat *self,
965
965
  PyObject *args)
966
966
  {
967
- std::unique_ptr<Measure *, decltype(free) *> measures(NULL, free);
967
+ std::unique_ptr<Measure *[]> measures;
968
968
  size_t len;
969
969
  FieldPosition dont_care(FieldPosition::DONT_CARE);
970
970
  FieldPosition *fp;
@@ -1288,7 +1288,7 @@ static PyObject *t_messageformat_getFormats(t_messageformat *self)
1288
1288
  static PyObject *t_messageformat_setFormats(t_messageformat *self,
1289
1289
  PyObject *arg)
1290
1290
  {
1291
- std::unique_ptr<Format *, decltype(free) *> formats(NULL, free);
1291
+ std::unique_ptr<Format *[]> formats;
1292
1292
  size_t len;
1293
1293
 
1294
1294
  if (!parseArg(arg, arg::Q<Format>(TYPE_ID(Format), &formats, &len)))
@@ -1142,33 +1142,25 @@ static PyObject *t_breakiterator_getRuleStatusVec(t_breakiterator *self)
1142
1142
 
1143
1143
  if (status == U_BUFFER_OVERFLOW_ERROR)
1144
1144
  {
1145
- int32_t *buffer = (int32_t *) calloc(count, sizeof(int32_t));
1145
+ std::unique_ptr<int32_t[]> buffer(new int32_t[count]);
1146
1146
 
1147
- if (buffer == NULL)
1147
+ if (!buffer.get())
1148
1148
  return PyErr_NoMemory();
1149
1149
 
1150
1150
  status = U_ZERO_ERROR;
1151
- count = self->object->getRuleStatusVec(buffer, count, status);
1151
+ count = self->object->getRuleStatusVec(buffer.get(), count, status);
1152
1152
 
1153
1153
  if (U_FAILURE(status))
1154
- {
1155
- free(buffer);
1156
1154
  return ICUException(status).reportError();
1157
- }
1158
1155
 
1159
1156
  PyObject *tuple = PyTuple_New(count);
1160
1157
 
1161
1158
  if (!tuple)
1162
- {
1163
- free(buffer);
1164
1159
  return NULL;
1165
- }
1166
1160
 
1167
1161
  for (int i = 0; i < count; ++i)
1168
1162
  PyTuple_SET_ITEM(tuple, i, PyInt_FromLong(buffer[i]));
1169
1163
 
1170
- free(buffer);
1171
-
1172
1164
  return tuple;
1173
1165
  }
1174
1166
 
@@ -2253,33 +2253,25 @@ static PyObject *t_localebuilder_build(t_localebuilder *self)
2253
2253
 
2254
2254
  #if U_ICU_VERSION_HEX >= VERSION_HEX(65, 0, 0)
2255
2255
 
2256
- // takes ownership of locales pointer array
2257
2256
  class LocaleIterator : public Locale::Iterator {
2258
2257
  public:
2259
- LocaleIterator(Locale **locales, int len) :
2260
- locales_(locales), len_(len),
2261
- current_(0)
2258
+ LocaleIterator(std::unique_ptr<Locale *[]> &&locales, int len) :
2259
+ locales(std::move(locales)), len(len), current(0)
2262
2260
  {}
2263
2261
 
2264
- ~LocaleIterator()
2265
- {
2266
- free(locales_); // allocated with calloc in pl2cpa in common.cpp
2267
- }
2268
-
2269
2262
  UBool hasNext() const override
2270
2263
  {
2271
- return current_ < len_;
2264
+ return current < len;
2272
2265
  }
2273
2266
 
2274
2267
  const Locale &next() override
2275
2268
  {
2276
- return *locales_[current_++];
2269
+ return *locales[current++];
2277
2270
  }
2278
2271
 
2279
2272
  private:
2280
- Locale **locales_;
2281
- int len_;
2282
- int current_;
2273
+ std::unique_ptr<Locale *[]> locales;
2274
+ int len, current;
2283
2275
  };
2284
2276
 
2285
2277
 
@@ -2322,12 +2314,12 @@ static PyObject *t_localematcherbuilder_setSupportedLocalesFromListString(
2322
2314
  static PyObject *t_localematcherbuilder_setSupportedLocales(
2323
2315
  t_localematcherbuilder *self, PyObject *arg)
2324
2316
  {
2325
- std::unique_ptr<Locale *, decltype(free) *> locales(NULL, free);
2317
+ std::unique_ptr<Locale *[]> locales;
2326
2318
  size_t len;
2327
2319
 
2328
2320
  if (!parseArg(arg, arg::Q<Locale>(TYPE_CLASSID(Locale), &locales, &len)))
2329
2321
  {
2330
- LocaleIterator it(locales.release(), len);
2322
+ LocaleIterator it(std::move(locales), len);
2331
2323
 
2332
2324
  self->object->setSupportedLocales(it);
2333
2325
  Py_RETURN_SELF();
@@ -2499,7 +2491,7 @@ static PyObject *t_localematcher_getBestMatch(t_localematcher *self,
2499
2491
  PyObject *arg)
2500
2492
  {
2501
2493
  Locale *locale;
2502
- std::unique_ptr<Locale *, decltype(free) *> locales(NULL, free);
2494
+ std::unique_ptr<Locale *[]> locales;
2503
2495
  size_t len;
2504
2496
 
2505
2497
  if (!parseArg(arg, arg::P<Locale>(TYPE_CLASSID(Locale), &locale)))
@@ -2512,7 +2504,7 @@ static PyObject *t_localematcher_getBestMatch(t_localematcher *self,
2512
2504
 
2513
2505
  if (!parseArg(arg, arg::Q<Locale>(TYPE_CLASSID(Locale), &locales, &len)))
2514
2506
  {
2515
- LocaleIterator it(locales.release(), len);
2507
+ LocaleIterator it(std::move(locales), len);
2516
2508
  const Locale *result;
2517
2509
 
2518
2510
  STATUS_CALL(result = self->object->getBestMatch(it, status));
@@ -2546,7 +2538,7 @@ static PyObject *t_localematcher_getBestMatchResult(
2546
2538
  t_localematcher *self, PyObject *arg)
2547
2539
  {
2548
2540
  Locale *locale;
2549
- std::unique_ptr<Locale *, decltype(free) *> locales(NULL, free);
2541
+ std::unique_ptr<Locale *[]> locales;
2550
2542
  size_t len;
2551
2543
 
2552
2544
  if (!parseArg(arg, arg::P<Locale>(TYPE_CLASSID(Locale), &locale)))
@@ -2559,7 +2551,7 @@ static PyObject *t_localematcher_getBestMatchResult(
2559
2551
 
2560
2552
  if (!parseArg(arg, arg::Q<Locale>(TYPE_CLASSID(Locale), &locales, &len)))
2561
2553
  {
2562
- LocaleIterator it(locales.release(), len);
2554
+ LocaleIterator it(std::move(locales), len);
2563
2555
 
2564
2556
  STATUS_RESULT_CALL(
2565
2557
  LocaleMatcherResult result = self->object->getBestMatchResult(
@@ -2608,17 +2600,11 @@ static PyObject *t_localematcher_acceptLanguage(PyTypeObject *type,
2608
2600
  arg::m(&accepts, &num_accepts),
2609
2601
  arg::m(&locales, &num_locales)))
2610
2602
  {
2611
- const char **accept_buffers =
2612
- (const char **) calloc(num_accepts, sizeof(char *));
2613
- const char **locale_buffers =
2614
- (const char **) calloc(num_locales, sizeof(char *));
2603
+ std::unique_ptr<const char *[]> accept_buffers(new const char *[num_accepts]);
2604
+ std::unique_ptr<const char *[]> locale_buffers(new const char *[num_locales]);
2615
2605
 
2616
- if (!accept_buffers || !locale_buffers)
2617
- {
2618
- free(locale_buffers);
2619
- free(accept_buffers);
2606
+ if (!accept_buffers.get() || !locale_buffers.get())
2620
2607
  return PyErr_NoMemory();
2621
- }
2622
2608
 
2623
2609
  for (size_t i = 0; i < num_accepts; ++i)
2624
2610
  accept_buffers[i] = accepts[i].c_str();
@@ -2628,14 +2614,10 @@ static PyObject *t_localematcher_acceptLanguage(PyTypeObject *type,
2628
2614
 
2629
2615
  UErrorCode status = U_ZERO_ERROR;
2630
2616
  UEnumeration *locale_enum = uenum_openCharStringsEnumeration(
2631
- locale_buffers, num_locales, &status);
2617
+ locale_buffers.get(), num_locales, &status);
2632
2618
 
2633
2619
  if (U_FAILURE(status))
2634
- {
2635
- free(locale_buffers);
2636
- free(accept_buffers);
2637
2620
  return ICUException(status).reportError();
2638
- }
2639
2621
  else
2640
2622
  status = U_ZERO_ERROR;
2641
2623
 
@@ -2643,11 +2625,9 @@ static PyObject *t_localematcher_acceptLanguage(PyTypeObject *type,
2643
2625
  char buffer[128];
2644
2626
  size_t size = uloc_acceptLanguage(
2645
2627
  buffer, sizeof(buffer), &result,
2646
- accept_buffers, num_accepts, locale_enum, &status);
2628
+ accept_buffers.get(), num_accepts, locale_enum, &status);
2647
2629
 
2648
2630
  uenum_close(locale_enum);
2649
- free(locale_buffers);
2650
- free(accept_buffers);
2651
2631
 
2652
2632
  if (U_FAILURE(status))
2653
2633
  return ICUException(status).reportError();
@@ -2682,10 +2662,9 @@ static PyObject *t_localematcher_acceptLanguageFromHTTP(PyTypeObject *type,
2682
2662
  arg::n(&header_value),
2683
2663
  arg::m(&locales, &num_locales)))
2684
2664
  {
2685
- const char **locale_buffers =
2686
- (const char **) calloc(num_locales, sizeof(char *));
2665
+ std::unique_ptr<const char *[]> locale_buffers(new const char *[num_locales]);
2687
2666
 
2688
- if (!locale_buffers)
2667
+ if (!locale_buffers.get())
2689
2668
  return PyErr_NoMemory();
2690
2669
 
2691
2670
  for (size_t i = 0; i < num_locales; ++i)
@@ -2693,13 +2672,10 @@ static PyObject *t_localematcher_acceptLanguageFromHTTP(PyTypeObject *type,
2693
2672
 
2694
2673
  UErrorCode status = U_ZERO_ERROR;
2695
2674
  UEnumeration *locale_enum = uenum_openCharStringsEnumeration(
2696
- locale_buffers, num_locales, &status);
2675
+ locale_buffers.get(), num_locales, &status);
2697
2676
 
2698
2677
  if (U_FAILURE(status))
2699
- {
2700
- free(locale_buffers);
2701
2678
  return ICUException(status).reportError();
2702
- }
2703
2679
  else
2704
2680
  status = U_ZERO_ERROR;
2705
2681
 
@@ -2710,7 +2686,6 @@ static PyObject *t_localematcher_acceptLanguageFromHTTP(PyTypeObject *type,
2710
2686
  header_value.c_str(), locale_enum, &status);
2711
2687
 
2712
2688
  uenum_close(locale_enum);
2713
- free(locale_buffers);
2714
2689
 
2715
2690
  if (U_FAILURE(status))
2716
2691
  return ICUException(status).reportError();
@@ -3003,11 +2978,23 @@ void _init_locale(PyObject *m)
3003
2978
 
3004
2979
  INSTALL_ENUM(ULocaleDataExemplarSetType, "ES_STANDARD",
3005
2980
  ULOCDATA_ES_STANDARD);
2981
+ INSTALL_ENUM(ULocaleDataExemplarSetType, "STANDARD",
2982
+ ULOCDATA_ES_STANDARD);
3006
2983
  INSTALL_ENUM(ULocaleDataExemplarSetType, "ES_AUXILIARY",
3007
2984
  ULOCDATA_ES_AUXILIARY);
2985
+ INSTALL_ENUM(ULocaleDataExemplarSetType, "AUXILIARY",
2986
+ ULOCDATA_ES_AUXILIARY);
3008
2987
  #if U_ICU_VERSION_HEX >= 0x04080000
3009
2988
  INSTALL_ENUM(ULocaleDataExemplarSetType, "ES_INDEX",
3010
2989
  ULOCDATA_ES_INDEX);
2990
+ INSTALL_ENUM(ULocaleDataExemplarSetType, "INDEX",
2991
+ ULOCDATA_ES_INDEX);
2992
+ #endif
2993
+ #if U_ICU_VERSION_HEX >= VERSION_HEX(51, 0, 0)
2994
+ INSTALL_ENUM(ULocaleDataExemplarSetType, "ES_PUNCTUATION",
2995
+ ULOCDATA_ES_PUNCTUATION);
2996
+ INSTALL_ENUM(ULocaleDataExemplarSetType, "PUNCTUATION",
2997
+ ULOCDATA_ES_PUNCTUATION);
3011
2998
  #endif
3012
2999
 
3013
3000
  INSTALL_ENUM(UMeasurementSystem, "SI", UMS_SI);
@@ -297,12 +297,21 @@ static PyObject *t_measureunit_createBeaufort(PyTypeObject *type);
297
297
  static PyObject *t_measureunit_createGasolineEnergyDensity(PyTypeObject *type);
298
298
  #endif
299
299
 
300
+ #if U_ICU_VERSION_HEX >= VERSION_HEX(76, 0, 0)
301
+ static PyObject *t_measureunit_createLightSpeed(PyTypeObject *type);
302
+ static PyObject *t_measureunit_createNight(PyTypeObject *type);
303
+ #endif
304
+
300
305
  #if U_ICU_VERSION_HEX >= VERSION_HEX(77, 0, 0)
301
- static PyObject *t_measureunit_createPortionPer1E9(PyTypeObject *type);
302
306
  static PyObject *t_measureunit_withConstantDenominator(t_measureunit *self, PyObject *arg);
303
307
  static PyObject *t_measureunit_getConstantDenominator(t_measureunit *self);
304
308
  #endif
305
309
 
310
+ #if U_ICU_VERSION_HEX >= VERSION_HEX(78, 0, 0)
311
+ static PyObject *t_measureunit_createPartPer1E6(PyTypeObject *type);
312
+ static PyObject *t_measureunit_createPartPer1E9(PyTypeObject *type);
313
+ #endif
314
+
306
315
  static PyMethodDef t_measureunit_methods[] = {
307
316
  #if U_ICU_VERSION_HEX >= VERSION_HEX(53, 0, 0)
308
317
  DECLARE_METHOD(t_measureunit, getType, METH_NOARGS),
@@ -543,10 +552,17 @@ static PyMethodDef t_measureunit_methods[] = {
543
552
  #if U_ICU_VERSION_HEX >= VERSION_HEX(74, 0, 0)
544
553
  DECLARE_METHOD(t_measureunit, createGasolineEnergyDensity, METH_NOARGS | METH_CLASS),
545
554
  #endif
555
+ #if U_ICU_VERSION_HEX >= VERSION_HEX(76, 0, 0)
556
+ DECLARE_METHOD(t_measureunit, createLightSpeed, METH_NOARGS | METH_CLASS),
557
+ DECLARE_METHOD(t_measureunit, createNight, METH_NOARGS | METH_CLASS),
558
+ #endif
546
559
  #if U_ICU_VERSION_HEX >= VERSION_HEX(77, 0, 0)
547
- DECLARE_METHOD(t_measureunit, createPortionPer1E9, METH_NOARGS | METH_CLASS),
548
560
  DECLARE_METHOD(t_measureunit, withConstantDenominator, METH_O),
549
561
  DECLARE_METHOD(t_measureunit, getConstantDenominator, METH_NOARGS),
562
+ #endif
563
+ #if U_ICU_VERSION_HEX >= VERSION_HEX(78, 0, 0)
564
+ DECLARE_METHOD(t_measureunit, createPartPer1E6, METH_NOARGS | METH_CLASS),
565
+ DECLARE_METHOD(t_measureunit, createPartPer1E9, METH_NOARGS | METH_CLASS),
550
566
  #endif
551
567
  { NULL, NULL, 0, NULL }
552
568
  };
@@ -1174,8 +1190,14 @@ createMU(Beaufort)
1174
1190
  createMU(GasolineEnergyDensity)
1175
1191
  #endif
1176
1192
 
1177
- #if U_ICU_VERSION_HEX >= VERSION_HEX(77, 0, 0)
1178
- createMU(PortionPer1E9)
1193
+ #if U_ICU_VERSION_HEX >= VERSION_HEX(76, 0, 0)
1194
+ createMU(LightSpeed)
1195
+ createMU(Night)
1196
+ #endif
1197
+
1198
+ #if U_ICU_VERSION_HEX >= VERSION_HEX(78, 0, 0)
1199
+ createMU(PartPer1E6)
1200
+ createMU(PartPer1E9)
1179
1201
  #endif
1180
1202
 
1181
1203
  /* Measure */
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyicu
3
- Version: 2.15.2
3
+ Version: 2.16
4
4
  Summary: Python extension wrapping the ICU C++ API
5
5
  Home-page: https://gitlab.pyicu.org/main/pyicu
6
6
  Author: Andi Vajda
@@ -594,6 +594,13 @@ void _init_script(PyObject *m)
594
594
  #if U_ICU_VERSION_HEX >= VERSION_HEX(75, 0, 0)
595
595
  INSTALL_ENUM(UScriptCode, "ARABIC_NASTALIQ", USCRIPT_ARABIC_NASTALIQ);
596
596
  #endif
597
+ #if U_ICU_VERSION_HEX >= VERSION_HEX(78, 0, 0)
598
+ INSTALL_ENUM(UScriptCode, "BERIA_ERFE", USCRIPT_BERIA_ERFE);
599
+ INSTALL_ENUM(UScriptCode, "SIDETIC", USCRIPT_SIDETIC);
600
+ INSTALL_ENUM(UScriptCode, "TAI_YO", USCRIPT_TAI_YO);
601
+ INSTALL_ENUM(UScriptCode, "TOLONG_SIKI", USCRIPT_TOLONG_SIKI);
602
+ INSTALL_ENUM(UScriptCode, "TRADITIONAL_HAN_WITH_LATIN", USCRIPT_TRADITIONAL_HAN_WITH_LATIN);
603
+ #endif
597
604
 
598
605
  #if U_ICU_VERSION_HEX >= VERSION_HEX(51, 0, 0)
599
606
  INSTALL_ENUM(UScriptUsage, "NOT_ENCODED", USCRIPT_USAGE_NOT_ENCODED);
@@ -8,8 +8,8 @@ except ImportError:
8
8
 
9
9
  from distutils.spawn import find_executable
10
10
 
11
- VERSION = '2.15.2'
12
- ICU_MAX_MAJOR_VERSION = '77' # max supported major version of ICU
11
+ VERSION = '2.16'
12
+ ICU_MAX_MAJOR_VERSION = '78' # max supported major version of ICU
13
13
 
14
14
  try:
15
15
  from subprocess import check_output as subprocess_check_output
@@ -1419,33 +1419,25 @@ static PyObject *t_basictimezone_getTimeZoneRules(t_basictimezone *self)
1419
1419
  STATUS_CALL(count = self->object->countTransitionRules(status));
1420
1420
 
1421
1421
  const InitialTimeZoneRule *initial;
1422
- const TimeZoneRule **rules =
1423
- (const TimeZoneRule **) calloc(count, sizeof(const TimeZoneRule *));
1424
- if (rules == NULL)
1422
+ std::unique_ptr<const TimeZoneRule *[]> rules(new const TimeZoneRule *[count]);
1423
+ if (!rules.get())
1425
1424
  return PyErr_NoMemory();
1426
1425
 
1427
1426
  UErrorCode status = U_ZERO_ERROR;
1428
1427
 
1429
- self->object->getTimeZoneRules(initial, rules, count, status);
1428
+ self->object->getTimeZoneRules(initial, rules.get(), count, status);
1430
1429
  if (U_FAILURE(status))
1431
- {
1432
- free(rules);
1433
1430
  return ICUException(status).reportError();
1434
- }
1435
1431
 
1436
1432
  PyObject *result = PyTuple_New(count + 1);
1437
1433
 
1438
1434
  if (result == NULL)
1439
- {
1440
- free(rules);
1441
1435
  return NULL;
1442
- }
1443
1436
 
1444
1437
  PyTuple_SET_ITEM(result, 0, wrap_TimeZoneRule(*initial));
1445
1438
  for (int i = 0; i < count; ++i)
1446
1439
  PyTuple_SET_ITEM(result, i + 1, wrap_TimeZoneRule(*rules[i]));
1447
1440
 
1448
- free(rules);
1449
1441
  return result;
1450
1442
  }
1451
1443
 
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
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
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
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
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
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
File without changes
File without changes
File without changes
File without changes