private-attribute-cpp 2.0.1__tar.gz → 2.0.3__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.
- {private_attribute_cpp-2.0.1/private_attribute_cpp.egg-info → private_attribute_cpp-2.0.3}/PKG-INFO +1 -1
- {private_attribute_cpp-2.0.1 → private_attribute_cpp-2.0.3}/private_attribute.cpp +104 -210
- {private_attribute_cpp-2.0.1 → private_attribute_cpp-2.0.3/private_attribute_cpp.egg-info}/PKG-INFO +1 -1
- {private_attribute_cpp-2.0.1 → private_attribute_cpp-2.0.3}/setup.py +1 -1
- {private_attribute_cpp-2.0.1 → private_attribute_cpp-2.0.3}/LICENSE +0 -0
- {private_attribute_cpp-2.0.1 → private_attribute_cpp-2.0.3}/MANIFEST.in +0 -0
- {private_attribute_cpp-2.0.1 → private_attribute_cpp-2.0.3}/README.md +0 -0
- {private_attribute_cpp-2.0.1 → private_attribute_cpp-2.0.3}/picosha2.h +0 -0
- {private_attribute_cpp-2.0.1 → private_attribute_cpp-2.0.3}/private_attribute.pyi +0 -0
- {private_attribute_cpp-2.0.1 → private_attribute_cpp-2.0.3}/private_attribute_cpp.egg-info/SOURCES.txt +0 -0
- {private_attribute_cpp-2.0.1 → private_attribute_cpp-2.0.3}/private_attribute_cpp.egg-info/dependency_links.txt +0 -0
- {private_attribute_cpp-2.0.1 → private_attribute_cpp-2.0.3}/private_attribute_cpp.egg-info/not-zip-safe +0 -0
- {private_attribute_cpp-2.0.1 → private_attribute_cpp-2.0.3}/private_attribute_cpp.egg-info/top_level.txt +0 -0
- {private_attribute_cpp-2.0.1 → private_attribute_cpp-2.0.3}/setup.cfg +0 -0
- {private_attribute_cpp-2.0.1 → private_attribute_cpp-2.0.3}/tests/test_class_private_attrs.py +0 -0
- {private_attribute_cpp-2.0.1 → private_attribute_cpp-2.0.3}/tests/test_private_abc.py +0 -0
- {private_attribute_cpp-2.0.1 → private_attribute_cpp-2.0.3}/tests/test_private_attrs.py +0 -0
- {private_attribute_cpp-2.0.1 → private_attribute_cpp-2.0.3}/tests/test_private_func.py +0 -0
- {private_attribute_cpp-2.0.1 → private_attribute_cpp-2.0.3}/tests/test_private_inheritance.py +0 -0
- {private_attribute_cpp-2.0.1 → private_attribute_cpp-2.0.3}/tests/test_private_method.py +0 -0
- {private_attribute_cpp-2.0.1 → private_attribute_cpp-2.0.3}/tests/test_private_wrap.py +0 -0
{private_attribute_cpp-2.0.1/private_attribute_cpp.egg-info → private_attribute_cpp-2.0.3}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: private_attribute_cpp
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.3
|
|
4
4
|
Summary: A Python package that provides a way to define private attributes in C++ implementation.
|
|
5
5
|
Home-page: https://github.com/Locked-chess-official/private_attribute_cpp
|
|
6
6
|
Author: HuangHaoHua
|
|
@@ -33,6 +33,12 @@ PyDict_ContainsString(PyObject *op, const char *key) noexcept
|
|
|
33
33
|
return res;
|
|
34
34
|
}
|
|
35
35
|
#endif
|
|
36
|
+
|
|
37
|
+
// python >= 3.15 has PyAnyDict_Check. Under 3.15 defined it as PyDict_Check
|
|
38
|
+
#if PY_VERSION_HEX < 0x030F0000
|
|
39
|
+
#define PyAnyDict_Check(op) PyDict_Check(op)
|
|
40
|
+
#endif
|
|
41
|
+
|
|
36
42
|
static const auto module_running_time = std::chrono::system_clock::now();
|
|
37
43
|
|
|
38
44
|
static std::string
|
|
@@ -277,178 +283,67 @@ default_random_string(uintptr_t obj_id, const std::string& attr_name) noexcept
|
|
|
277
283
|
return result;
|
|
278
284
|
}
|
|
279
285
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
RestorePythonException(PyObject* type, PyObject* value, PyObject* traceback) noexcept
|
|
284
|
-
: type(type), value(value), traceback(traceback) {
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
~RestorePythonException() noexcept {
|
|
288
|
-
Py_XDECREF(type);
|
|
289
|
-
Py_XDECREF(value);
|
|
290
|
-
Py_XDECREF(traceback);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
RestorePythonException(const RestorePythonException&) = delete;
|
|
294
|
-
RestorePythonException& operator=(RestorePythonException&& other) noexcept {
|
|
295
|
-
if (this != &other) {
|
|
296
|
-
type = other.type;
|
|
297
|
-
value = other.value;
|
|
298
|
-
traceback = other.traceback;
|
|
299
|
-
other.type = nullptr;
|
|
300
|
-
other.value = nullptr;
|
|
301
|
-
other.traceback = nullptr;
|
|
302
|
-
}
|
|
303
|
-
return *this;
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
// Move constructor
|
|
307
|
-
RestorePythonException(RestorePythonException&& other) noexcept
|
|
308
|
-
: type(other.type), value(other.value), traceback(other.traceback) {
|
|
309
|
-
other.type = nullptr;
|
|
310
|
-
other.value = nullptr;
|
|
311
|
-
other.traceback = nullptr;
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
void restore() noexcept {
|
|
315
|
-
PyErr_Restore(type, value, traceback);
|
|
316
|
-
type = value = traceback = nullptr;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
const char* what() const noexcept override {
|
|
320
|
-
if (!msg_.empty())
|
|
321
|
-
return msg_.c_str();
|
|
322
|
-
|
|
323
|
-
if (!type || !value) {
|
|
324
|
-
msg_ = "cannot format this exception (missing type/value)";
|
|
325
|
-
return msg_.c_str();
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
PyObject* tb_mod = PyImport_ImportModule("traceback");
|
|
329
|
-
if (!tb_mod) {
|
|
330
|
-
msg_ = "cannot format this exception (import traceback failed)";
|
|
331
|
-
return msg_.c_str();
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
PyObject* format_exc = PyObject_GetAttrString(tb_mod, "format_exception");
|
|
335
|
-
Py_DECREF(tb_mod);
|
|
336
|
-
if (!format_exc) {
|
|
337
|
-
msg_ = "cannot format this exception (get format_exception failed)";
|
|
338
|
-
return msg_.c_str();
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
PyObject* result = PyObject_CallFunctionObjArgs(
|
|
342
|
-
format_exc, type, value, traceback ? traceback : Py_None, nullptr);
|
|
343
|
-
Py_DECREF(format_exc);
|
|
344
|
-
|
|
345
|
-
if (!result) {
|
|
346
|
-
msg_ = "cannot format this exception (format_exception failed)";
|
|
347
|
-
return msg_.c_str();
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
PyObject* empty = PyUnicode_FromString("");
|
|
351
|
-
if (!empty) {
|
|
352
|
-
Py_DECREF(result);
|
|
353
|
-
msg_ = "cannot format this exception (create empty string failed)";
|
|
354
|
-
return msg_.c_str();
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
PyObject* joined = PyUnicode_Join(empty, result);
|
|
358
|
-
Py_DECREF(empty);
|
|
359
|
-
Py_DECREF(result);
|
|
360
|
-
|
|
361
|
-
if (!joined) {
|
|
362
|
-
msg_ = "cannot format this exception (join failed)";
|
|
363
|
-
return msg_.c_str();
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
const char* utf8 = PyUnicode_AsUTF8(joined);
|
|
367
|
-
if (utf8)
|
|
368
|
-
msg_ = utf8;
|
|
369
|
-
else
|
|
370
|
-
msg_ = "cannot format this exception (AsUTF8 failed)";
|
|
371
|
-
|
|
372
|
-
Py_DECREF(joined);
|
|
373
|
-
return msg_.c_str();
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
private:
|
|
377
|
-
PyObject* type = nullptr;
|
|
378
|
-
PyObject* value = nullptr;
|
|
379
|
-
PyObject* traceback = nullptr;
|
|
380
|
-
mutable std::string msg_;
|
|
286
|
+
struct RestorePythonExceptionResult {
|
|
287
|
+
std::string value;
|
|
288
|
+
bool ok = true;
|
|
381
289
|
};
|
|
382
290
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
#ifdef _MSC_VER
|
|
386
|
-
#pragma warning(push)
|
|
387
|
-
#pragma warning(disable: 5272)
|
|
388
|
-
#endif
|
|
389
|
-
|
|
390
|
-
static std::string
|
|
391
|
-
custom_random_string(uintptr_t obj_id, const std::string& attr_name, PyObject* func)
|
|
291
|
+
static RestorePythonExceptionResult
|
|
292
|
+
custom_random_string(uintptr_t obj_id, const std::string& attr_name, PyObject* func) noexcept
|
|
392
293
|
{
|
|
294
|
+
RestorePythonExceptionResult result;
|
|
393
295
|
AllPyobjectAttrCacheKey key(obj_id, attr_name);
|
|
394
|
-
std::string result;
|
|
395
296
|
{
|
|
396
297
|
std::shared_lock<std::shared_mutex> lock(::AllData::cache_mutex);
|
|
397
298
|
auto it = ::AllData::cache.find(key);
|
|
398
299
|
if (it != ::AllData::cache.end()) {
|
|
399
|
-
result = it->second;
|
|
300
|
+
result.value = it->second;
|
|
400
301
|
return result;
|
|
401
302
|
} else {
|
|
402
303
|
lock.unlock();
|
|
403
|
-
PyObject*
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
Py_DECREF(args);
|
|
304
|
+
PyObject* python_result = PyObject_CallFunction(
|
|
305
|
+
func,
|
|
306
|
+
"ns",
|
|
307
|
+
static_cast<Py_ssize_t>(obj_id),
|
|
308
|
+
attr_name.c_str()
|
|
309
|
+
);
|
|
410
310
|
if (python_result) {
|
|
411
311
|
if (!PyUnicode_Check(python_result)) {
|
|
412
312
|
Py_DECREF(python_result);
|
|
413
313
|
PyErr_SetString(PyExc_TypeError, "private_func function must return a string");
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
314
|
+
result.ok = false;
|
|
315
|
+
result.value = "private_func function must return a string";
|
|
316
|
+
return result;
|
|
417
317
|
}
|
|
418
|
-
result = PyUnicode_AsUTF8(python_result);
|
|
318
|
+
result.value = PyUnicode_AsUTF8(python_result);
|
|
419
319
|
Py_DECREF(python_result);
|
|
420
|
-
std::string original_result = result;
|
|
320
|
+
std::string original_result = result.value;
|
|
421
321
|
unsigned long long i = 1;
|
|
422
322
|
std::unique_lock<std::shared_mutex> lock2(::AllData::cache_mutex);
|
|
423
323
|
auto it = ::AllData::cache.find(key); // twice check
|
|
424
324
|
if (it != ::AllData::cache.end()) {
|
|
425
|
-
result = it->second;
|
|
325
|
+
result.value = it->second;
|
|
426
326
|
return result;
|
|
427
327
|
}
|
|
428
|
-
while (::AllData::all_exist_name.find(result) != ::AllData::all_exist_name.end()) {
|
|
429
|
-
result = original_result + "_" + std::to_string(i);
|
|
328
|
+
while (::AllData::all_exist_name.find(result.value) != ::AllData::all_exist_name.end()) {
|
|
329
|
+
result.value = original_result + "_" + std::to_string(i);
|
|
430
330
|
i++;
|
|
431
331
|
}
|
|
432
332
|
if (::AllData::obj_attr_keys.find(obj_id) == ::AllData::obj_attr_keys.end()) {
|
|
433
333
|
::AllData::obj_attr_keys[obj_id] = {};
|
|
434
334
|
}
|
|
435
335
|
::AllData::obj_attr_keys[obj_id].push_back(key);
|
|
436
|
-
::AllData::cache[key] = result;
|
|
437
|
-
::AllData::all_exist_name.insert(result);
|
|
336
|
+
::AllData::cache[key] = result.value;
|
|
337
|
+
::AllData::all_exist_name.insert(result.value);
|
|
438
338
|
} else {
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
throw RestorePythonException(type, value, traceback);
|
|
339
|
+
result.ok = false;
|
|
340
|
+
result.value = "python exception while calling private function";
|
|
442
341
|
}
|
|
443
342
|
}
|
|
444
343
|
}
|
|
445
344
|
return result;
|
|
446
345
|
}
|
|
447
346
|
|
|
448
|
-
#ifdef _MSC_VER
|
|
449
|
-
#pragma warning(pop)
|
|
450
|
-
#endif
|
|
451
|
-
|
|
452
347
|
static void
|
|
453
348
|
clear_obj(uintptr_t obj_id) noexcept
|
|
454
349
|
{
|
|
@@ -500,12 +395,11 @@ id_getattr(const std::string& attr_name, PyObject* obj, PyObject* typ) noexcept
|
|
|
500
395
|
obj_need_call = ::AllData::type_need_call[final_id];
|
|
501
396
|
}
|
|
502
397
|
if (obj_need_call) {
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
} catch (RestorePythonException& e) {
|
|
506
|
-
e.restore();
|
|
398
|
+
auto private_name_result = custom_random_string(obj_id, attr_name, obj_need_call);
|
|
399
|
+
if (!private_name_result.ok) {
|
|
507
400
|
return NULL;
|
|
508
401
|
}
|
|
402
|
+
obj_private_name = private_name_result.value;
|
|
509
403
|
} else {
|
|
510
404
|
obj_private_name = default_random_string(obj_id, attr_name);
|
|
511
405
|
}
|
|
@@ -582,9 +476,7 @@ id_getattr(const std::string& attr_name, PyObject* obj, PyObject* typ) noexcept
|
|
|
582
476
|
if (type_name == NULL) {
|
|
583
477
|
return NULL;
|
|
584
478
|
}
|
|
585
|
-
|
|
586
|
-
std::string exception_information = "'" + string_type_name + "' objects has no attribute '" + attr_name + "'";
|
|
587
|
-
PyErr_SetString(PyExc_AttributeError, exception_information.c_str());
|
|
479
|
+
PyErr_Format(PyExc_AttributeError, "'%s' object has no attribute '%s'", type_name, attr_name.c_str());
|
|
588
480
|
return NULL;
|
|
589
481
|
}
|
|
590
482
|
|
|
@@ -616,9 +508,7 @@ type_getattr(PyObject* typ, const std::string& attr_name) noexcept
|
|
|
616
508
|
if (type_name == NULL) {
|
|
617
509
|
return NULL;
|
|
618
510
|
}
|
|
619
|
-
|
|
620
|
-
std::string message = "type object '" + string_type_name + "' has no attribute '" + attr_name + "'";
|
|
621
|
-
PyErr_SetString(PyExc_AttributeError, message.c_str());
|
|
511
|
+
PyErr_Format(PyExc_AttributeError, "'%s' object has no attribute '%s'", type_name, attr_name.c_str());
|
|
622
512
|
return NULL;
|
|
623
513
|
}
|
|
624
514
|
|
|
@@ -641,12 +531,11 @@ id_setattr(const std::string& attr_name, PyObject* obj, PyObject* typ, PyObject*
|
|
|
641
531
|
obj_need_call = ::AllData::type_need_call[final_id];
|
|
642
532
|
}
|
|
643
533
|
if (obj_need_call) {
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
} catch (RestorePythonException& e) {
|
|
647
|
-
e.restore();
|
|
534
|
+
auto private_name_result = custom_random_string(obj_id, attr_name, obj_need_call);
|
|
535
|
+
if (!private_name_result.ok) {
|
|
648
536
|
return -1;
|
|
649
537
|
}
|
|
538
|
+
obj_private_name = private_name_result.value;
|
|
650
539
|
} else {
|
|
651
540
|
obj_private_name = default_random_string(obj_id, attr_name);
|
|
652
541
|
}
|
|
@@ -710,12 +599,11 @@ type_setattr(PyObject* typ, const std::string& attr_name, PyObject* value) noexc
|
|
|
710
599
|
type_need_call = NULL;
|
|
711
600
|
}
|
|
712
601
|
if (type_need_call) {
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
} catch (RestorePythonException& e) {
|
|
716
|
-
e.restore();
|
|
602
|
+
auto private_name_result = custom_random_string(typ_id, attr_name, type_need_call);
|
|
603
|
+
if (!private_name_result.ok) {
|
|
717
604
|
return -1;
|
|
718
605
|
}
|
|
606
|
+
final_key = private_name_result.value;
|
|
719
607
|
} else {
|
|
720
608
|
final_key = default_random_string(typ_id, attr_name);
|
|
721
609
|
}
|
|
@@ -785,12 +673,11 @@ id_delattr(const std::string& attr_name, PyObject* obj, PyObject* typ) noexcept
|
|
|
785
673
|
obj_need_call = ::AllData::type_need_call[final_id];
|
|
786
674
|
}
|
|
787
675
|
if (obj_need_call) {
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
} catch (RestorePythonException& e) {
|
|
791
|
-
e.restore();
|
|
676
|
+
auto private_name_result = custom_random_string(obj_id, attr_name, obj_need_call);
|
|
677
|
+
if (!private_name_result.ok) {
|
|
792
678
|
return -1;
|
|
793
679
|
}
|
|
680
|
+
obj_private_name = private_name_result.value;
|
|
794
681
|
} else {
|
|
795
682
|
obj_private_name = default_random_string(obj_id, attr_name);
|
|
796
683
|
}
|
|
@@ -832,10 +719,7 @@ id_delattr(const std::string& attr_name, PyObject* obj, PyObject* typ) noexcept
|
|
|
832
719
|
if (type_name == NULL) {
|
|
833
720
|
return -1;
|
|
834
721
|
}
|
|
835
|
-
|
|
836
|
-
std::string exception_information = "'" + string_type_name + "' objects has no attribute '" + attr_name + "'";
|
|
837
|
-
PyErr_SetString(PyExc_AttributeError, exception_information.c_str());
|
|
838
|
-
return -1;
|
|
722
|
+
PyErr_Format(PyExc_AttributeError, "'%s' object has no attribute '%s'", type_name, attr_name.c_str());
|
|
839
723
|
}
|
|
840
724
|
PyObject* delete_obj = ::AllData::all_object_attr[final_id][obj_id][obj_private_name];
|
|
841
725
|
::AllData::all_object_attr[final_id][obj_id].erase(obj_private_name);
|
|
@@ -857,12 +741,11 @@ type_delattr(PyObject* typ, const std::string& attr_name) noexcept
|
|
|
857
741
|
type_need_call = NULL;
|
|
858
742
|
}
|
|
859
743
|
if (type_need_call) {
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
} catch (RestorePythonException& e) {
|
|
863
|
-
e.restore();
|
|
744
|
+
auto private_name_result = custom_random_string(typ_id, attr_name, type_need_call);
|
|
745
|
+
if (!private_name_result.ok) {
|
|
864
746
|
return -1;
|
|
865
747
|
}
|
|
748
|
+
final_key = private_name_result.value;
|
|
866
749
|
} else {
|
|
867
750
|
final_key = default_random_string(typ_id, attr_name);
|
|
868
751
|
}
|
|
@@ -884,9 +767,7 @@ type_delattr(PyObject* typ, const std::string& attr_name) noexcept
|
|
|
884
767
|
if (type_name == NULL) {
|
|
885
768
|
return -1;
|
|
886
769
|
}
|
|
887
|
-
|
|
888
|
-
std::string message = "type object '" + string_type_name + "' has no attribute '" + attr_name + "'";
|
|
889
|
-
PyErr_SetString(PyExc_AttributeError, message.c_str());
|
|
770
|
+
PyErr_Format(PyExc_AttributeError, "type object '%s' has no attribute '%s'", type_name, attr_name.c_str());
|
|
890
771
|
return -1;
|
|
891
772
|
}
|
|
892
773
|
PyObject* delete_obj = ::AllData::type_attr_dict[typ_id][final_key];
|
|
@@ -912,9 +793,7 @@ type_delattr(PyObject* typ, const std::string& attr_name) noexcept
|
|
|
912
793
|
if (type_name == NULL) {
|
|
913
794
|
return -1;
|
|
914
795
|
}
|
|
915
|
-
|
|
916
|
-
std::string message = "type object '" + string_type_name + "' has no attribute '" + attr_name + "'";
|
|
917
|
-
PyErr_SetString(PyExc_AttributeError, message.c_str());
|
|
796
|
+
PyErr_Format(PyExc_AttributeError, "type object '%s' has no attribute '%s'", type_name, attr_name.c_str());
|
|
918
797
|
return -1;
|
|
919
798
|
}
|
|
920
799
|
PyObject* delete_obj = ::AllData::all_type_subclass_attr[final_id][typ_id][final_key];
|
|
@@ -1577,12 +1456,11 @@ type_get_final_attr(uintptr_t type_id, const std::string& name) noexcept
|
|
|
1577
1456
|
}
|
|
1578
1457
|
std::string key;
|
|
1579
1458
|
if (type_need_call != NULL) {
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
} catch (RestorePythonException& e) {
|
|
1583
|
-
e.restore();
|
|
1459
|
+
auto private_name_result = custom_random_string(type_id, name, type_need_call);
|
|
1460
|
+
if (!private_name_result.ok) {
|
|
1584
1461
|
return -2; // -2 means exception
|
|
1585
1462
|
}
|
|
1463
|
+
key = private_name_result.value;
|
|
1586
1464
|
} else {
|
|
1587
1465
|
key = default_random_string(type_id, name);
|
|
1588
1466
|
}
|
|
@@ -1616,12 +1494,11 @@ type_get_final_attr(uintptr_t type_id, const std::string& name) noexcept
|
|
|
1616
1494
|
if (::AllData::type_need_call.find(now_visited_id) != ::AllData::type_need_call.end()) {
|
|
1617
1495
|
PyObject* func = ::AllData::type_need_call[now_visited_id];
|
|
1618
1496
|
if (func != NULL) {
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
} catch (RestorePythonException& e) {
|
|
1622
|
-
e.restore();
|
|
1497
|
+
auto private_name_result = custom_random_string(now_visited_id, name, func);
|
|
1498
|
+
if (!private_name_result.ok) {
|
|
1623
1499
|
return -2; // -2 means exception
|
|
1624
1500
|
}
|
|
1501
|
+
key = private_name_result.value;
|
|
1625
1502
|
} else {
|
|
1626
1503
|
key = default_random_string(now_visited_id, name);
|
|
1627
1504
|
}
|
|
@@ -1647,12 +1524,11 @@ type_get_final_attr(uintptr_t type_id, const std::string& name) noexcept
|
|
|
1647
1524
|
if (::AllData::type_need_call.find(parent_id) != ::AllData::type_need_call.end()) {
|
|
1648
1525
|
PyObject* func = ::AllData::type_need_call[parent_id];
|
|
1649
1526
|
if (func != NULL) {
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
} catch (RestorePythonException& e) {
|
|
1653
|
-
e.restore();
|
|
1527
|
+
auto private_name_result = custom_random_string(parent_id, name, func);
|
|
1528
|
+
if (!private_name_result.ok) {
|
|
1654
1529
|
return -2; // -2 means exception
|
|
1655
1530
|
}
|
|
1531
|
+
key = private_name_result.value;
|
|
1656
1532
|
} else {
|
|
1657
1533
|
key = default_random_string(parent_id, name);
|
|
1658
1534
|
}
|
|
@@ -1975,7 +1851,7 @@ PrivateAttrType_preprocess(PyObject* args, PyObject* kwds, PrivateAttrCreationDa
|
|
|
1975
1851
|
return false;
|
|
1976
1852
|
}
|
|
1977
1853
|
|
|
1978
|
-
if (!
|
|
1854
|
+
if (!PyAnyDict_Check(data.attrs)) {
|
|
1979
1855
|
PyErr_SetString(PyExc_TypeError, "attrs must be a dict");
|
|
1980
1856
|
return false;
|
|
1981
1857
|
}
|
|
@@ -2050,26 +1926,46 @@ PrivateAttrType_preprocess(PyObject* args, PyObject* kwds, PrivateAttrCreationDa
|
|
|
2050
1926
|
|
|
2051
1927
|
if (has_slots) {
|
|
2052
1928
|
PyObject* all_slots = PyDict_GetItemString(data.attrs_copy, "__slots__");
|
|
2053
|
-
|
|
2054
|
-
if (
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
Py_DECREF(slot_seq);
|
|
1929
|
+
if (!all_slots) {return false;}
|
|
1930
|
+
if (PyUnicode_Check(all_slots)) {
|
|
1931
|
+
const char* slot_cstr = PyUnicode_AsUTF8(all_slots);
|
|
1932
|
+
if (data.private_attrs_vector_string.find((std::string)slot_cstr) != data.private_attrs_vector_string.end()){
|
|
1933
|
+
std::string error_msg = "'__slots__' and '__private_attrs__' cannot have the same attribute name: '" + std::string(slot_cstr) + "'";
|
|
1934
|
+
PyErr_SetString(PyExc_TypeError, error_msg.c_str());
|
|
1935
|
+
return false;
|
|
1936
|
+
}
|
|
1937
|
+
} else {
|
|
1938
|
+
PyObject* slot_seq;
|
|
1939
|
+
if (PyAnyDict_Check(all_slots)) {
|
|
1940
|
+
// use the key of the dict as the slot name
|
|
1941
|
+
PyObject* keys = PyDict_Keys(all_slots);
|
|
1942
|
+
if (!keys) {
|
|
2068
1943
|
return false;
|
|
2069
1944
|
}
|
|
1945
|
+
slot_seq = keys;
|
|
1946
|
+
} else {
|
|
1947
|
+
slot_seq = PySequence_Fast(all_slots, "__slots__ must be a sequence");
|
|
1948
|
+
}
|
|
1949
|
+
if (!slot_seq) {
|
|
1950
|
+
return false;
|
|
1951
|
+
}
|
|
1952
|
+
|
|
1953
|
+
Py_ssize_t slot_len = PySequence_Fast_GET_SIZE(slot_seq);
|
|
1954
|
+
|
|
1955
|
+
for (Py_ssize_t j = 0; j < slot_len; j++) {
|
|
1956
|
+
PyObject* slot = PySequence_Fast_GET_ITEM(slot_seq, j);
|
|
1957
|
+
if (PyUnicode_Check(slot)) {
|
|
1958
|
+
const char* slot_cstr = PyUnicode_AsUTF8(slot);
|
|
1959
|
+
if (data.private_attrs_vector_string.find((std::string)slot_cstr) != data.private_attrs_vector_string.end()){
|
|
1960
|
+
std::string error_msg = "'__slots__' and '__private_attrs__' cannot have the same attribute name: '" + std::string(slot_cstr) + "'";
|
|
1961
|
+
PyErr_SetString(PyExc_TypeError, error_msg.c_str());
|
|
1962
|
+
Py_DECREF(slot_seq);
|
|
1963
|
+
return false;
|
|
1964
|
+
}
|
|
1965
|
+
}
|
|
2070
1966
|
}
|
|
1967
|
+
Py_DECREF(slot_seq);
|
|
2071
1968
|
}
|
|
2072
|
-
Py_DECREF(slot_seq);
|
|
2073
1969
|
}
|
|
2074
1970
|
|
|
2075
1971
|
Py_ssize_t bases_len = PyTuple_GET_SIZE(data.bases);
|
|
@@ -2312,12 +2208,11 @@ PrivateAttrType_postprocess(PyObject* new_type, PrivateAttrCreationData& data) n
|
|
|
2312
2208
|
for (auto& [key, value]: data.need_remove_itself) {
|
|
2313
2209
|
std::string final_key;
|
|
2314
2210
|
if (data.private_func) {
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
} catch (RestorePythonException& e) {
|
|
2318
|
-
e.restore();
|
|
2211
|
+
auto private_name_result = custom_random_string(type_id, key, data.private_func);
|
|
2212
|
+
if (!private_name_result.ok) {
|
|
2319
2213
|
return false;
|
|
2320
2214
|
}
|
|
2215
|
+
final_key = private_name_result.value;
|
|
2321
2216
|
} else {
|
|
2322
2217
|
final_key = default_random_string(type_id, key);
|
|
2323
2218
|
}
|
|
@@ -2341,12 +2236,11 @@ PrivateAttrType_postprocess(PyObject* new_type, PrivateAttrCreationData& data) n
|
|
|
2341
2236
|
for (auto& [key, value]: map) {
|
|
2342
2237
|
std::string final_key;
|
|
2343
2238
|
if (data.private_func) {
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
} catch (RestorePythonException& e) {
|
|
2347
|
-
e.restore();
|
|
2239
|
+
auto private_name_result = custom_random_string(type_id, key, data.private_func);
|
|
2240
|
+
if (!private_name_result.ok) {
|
|
2348
2241
|
return false;
|
|
2349
2242
|
}
|
|
2243
|
+
final_key = private_name_result.value;
|
|
2350
2244
|
} else {
|
|
2351
2245
|
final_key = default_random_string(type_id, key);
|
|
2352
2246
|
}
|
|
@@ -3136,7 +3030,7 @@ PrivateModule_setattro(PyObject* self, PyObject* name, PyObject* value) noexcept
|
|
|
3136
3030
|
const size_t num_attrs = sizeof(unsetable_attrs) / sizeof(unsetable_attrs[0]);
|
|
3137
3031
|
for (size_t i = 0; i < num_attrs; ++i) {
|
|
3138
3032
|
if (strcmp(name_cstr, unsetable_attrs[i]) == 0) {
|
|
3139
|
-
PyErr_Format(PyExc_AttributeError, "attribute '%s' of 'private_attribute_module' objects is not writable", name_cstr);
|
|
3033
|
+
PyErr_Format(PyExc_AttributeError, "attribute '%s' of 'private_attribute.private_attribute_module' objects is not writable", name_cstr);
|
|
3140
3034
|
return -1;
|
|
3141
3035
|
}
|
|
3142
3036
|
}
|
{private_attribute_cpp-2.0.1 → private_attribute_cpp-2.0.3/private_attribute_cpp.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: private_attribute_cpp
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.3
|
|
4
4
|
Summary: A Python package that provides a way to define private attributes in C++ implementation.
|
|
5
5
|
Home-page: https://github.com/Locked-chess-official/private_attribute_cpp
|
|
6
6
|
Author: HuangHaoHua
|
|
@@ -18,7 +18,7 @@ readme = open('README.md').read()
|
|
|
18
18
|
|
|
19
19
|
setup(
|
|
20
20
|
name='private_attribute_cpp',
|
|
21
|
-
version='2.0.
|
|
21
|
+
version='2.0.3',
|
|
22
22
|
author="HuangHaoHua",
|
|
23
23
|
author_email="13140752715@example.com",
|
|
24
24
|
description='A Python package that provides a way to define private attributes in C++ implementation.',
|
|
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
|
{private_attribute_cpp-2.0.1 → private_attribute_cpp-2.0.3}/tests/test_class_private_attrs.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{private_attribute_cpp-2.0.1 → private_attribute_cpp-2.0.3}/tests/test_private_inheritance.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|