private-attribute-cpp 2.0.0__tar.gz → 2.0.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.
- {private_attribute_cpp-2.0.0/private_attribute_cpp.egg-info → private_attribute_cpp-2.0.2}/PKG-INFO +1 -1
- {private_attribute_cpp-2.0.0 → private_attribute_cpp-2.0.2}/private_attribute.cpp +68 -181
- {private_attribute_cpp-2.0.0 → private_attribute_cpp-2.0.2/private_attribute_cpp.egg-info}/PKG-INFO +1 -1
- {private_attribute_cpp-2.0.0 → private_attribute_cpp-2.0.2}/setup.py +1 -1
- {private_attribute_cpp-2.0.0 → private_attribute_cpp-2.0.2}/LICENSE +0 -0
- {private_attribute_cpp-2.0.0 → private_attribute_cpp-2.0.2}/MANIFEST.in +0 -0
- {private_attribute_cpp-2.0.0 → private_attribute_cpp-2.0.2}/README.md +0 -0
- {private_attribute_cpp-2.0.0 → private_attribute_cpp-2.0.2}/picosha2.h +0 -0
- {private_attribute_cpp-2.0.0 → private_attribute_cpp-2.0.2}/private_attribute.pyi +0 -0
- {private_attribute_cpp-2.0.0 → private_attribute_cpp-2.0.2}/private_attribute_cpp.egg-info/SOURCES.txt +0 -0
- {private_attribute_cpp-2.0.0 → private_attribute_cpp-2.0.2}/private_attribute_cpp.egg-info/dependency_links.txt +0 -0
- {private_attribute_cpp-2.0.0 → private_attribute_cpp-2.0.2}/private_attribute_cpp.egg-info/not-zip-safe +0 -0
- {private_attribute_cpp-2.0.0 → private_attribute_cpp-2.0.2}/private_attribute_cpp.egg-info/top_level.txt +0 -0
- {private_attribute_cpp-2.0.0 → private_attribute_cpp-2.0.2}/setup.cfg +0 -0
- {private_attribute_cpp-2.0.0 → private_attribute_cpp-2.0.2}/tests/test_class_private_attrs.py +0 -0
- {private_attribute_cpp-2.0.0 → private_attribute_cpp-2.0.2}/tests/test_private_abc.py +0 -0
- {private_attribute_cpp-2.0.0 → private_attribute_cpp-2.0.2}/tests/test_private_attrs.py +0 -0
- {private_attribute_cpp-2.0.0 → private_attribute_cpp-2.0.2}/tests/test_private_func.py +0 -0
- {private_attribute_cpp-2.0.0 → private_attribute_cpp-2.0.2}/tests/test_private_inheritance.py +0 -0
- {private_attribute_cpp-2.0.0 → private_attribute_cpp-2.0.2}/tests/test_private_method.py +0 -0
- {private_attribute_cpp-2.0.0 → private_attribute_cpp-2.0.2}/tests/test_private_wrap.py +0 -0
{private_attribute_cpp-2.0.0/private_attribute_cpp.egg-info → private_attribute_cpp-2.0.2}/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.2
|
|
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
|
}
|
|
@@ -641,12 +535,11 @@ id_setattr(const std::string& attr_name, PyObject* obj, PyObject* typ, PyObject*
|
|
|
641
535
|
obj_need_call = ::AllData::type_need_call[final_id];
|
|
642
536
|
}
|
|
643
537
|
if (obj_need_call) {
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
} catch (RestorePythonException& e) {
|
|
647
|
-
e.restore();
|
|
538
|
+
auto private_name_result = custom_random_string(obj_id, attr_name, obj_need_call);
|
|
539
|
+
if (!private_name_result.ok) {
|
|
648
540
|
return -1;
|
|
649
541
|
}
|
|
542
|
+
obj_private_name = private_name_result.value;
|
|
650
543
|
} else {
|
|
651
544
|
obj_private_name = default_random_string(obj_id, attr_name);
|
|
652
545
|
}
|
|
@@ -710,12 +603,11 @@ type_setattr(PyObject* typ, const std::string& attr_name, PyObject* value) noexc
|
|
|
710
603
|
type_need_call = NULL;
|
|
711
604
|
}
|
|
712
605
|
if (type_need_call) {
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
} catch (RestorePythonException& e) {
|
|
716
|
-
e.restore();
|
|
606
|
+
auto private_name_result = custom_random_string(typ_id, attr_name, type_need_call);
|
|
607
|
+
if (!private_name_result.ok) {
|
|
717
608
|
return -1;
|
|
718
609
|
}
|
|
610
|
+
final_key = private_name_result.value;
|
|
719
611
|
} else {
|
|
720
612
|
final_key = default_random_string(typ_id, attr_name);
|
|
721
613
|
}
|
|
@@ -785,12 +677,11 @@ id_delattr(const std::string& attr_name, PyObject* obj, PyObject* typ) noexcept
|
|
|
785
677
|
obj_need_call = ::AllData::type_need_call[final_id];
|
|
786
678
|
}
|
|
787
679
|
if (obj_need_call) {
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
} catch (RestorePythonException& e) {
|
|
791
|
-
e.restore();
|
|
680
|
+
auto private_name_result = custom_random_string(obj_id, attr_name, obj_need_call);
|
|
681
|
+
if (!private_name_result.ok) {
|
|
792
682
|
return -1;
|
|
793
683
|
}
|
|
684
|
+
obj_private_name = private_name_result.value;
|
|
794
685
|
} else {
|
|
795
686
|
obj_private_name = default_random_string(obj_id, attr_name);
|
|
796
687
|
}
|
|
@@ -857,12 +748,11 @@ type_delattr(PyObject* typ, const std::string& attr_name) noexcept
|
|
|
857
748
|
type_need_call = NULL;
|
|
858
749
|
}
|
|
859
750
|
if (type_need_call) {
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
} catch (RestorePythonException& e) {
|
|
863
|
-
e.restore();
|
|
751
|
+
auto private_name_result = custom_random_string(typ_id, attr_name, type_need_call);
|
|
752
|
+
if (!private_name_result.ok) {
|
|
864
753
|
return -1;
|
|
865
754
|
}
|
|
755
|
+
final_key = private_name_result.value;
|
|
866
756
|
} else {
|
|
867
757
|
final_key = default_random_string(typ_id, attr_name);
|
|
868
758
|
}
|
|
@@ -1577,12 +1467,11 @@ type_get_final_attr(uintptr_t type_id, const std::string& name) noexcept
|
|
|
1577
1467
|
}
|
|
1578
1468
|
std::string key;
|
|
1579
1469
|
if (type_need_call != NULL) {
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
} catch (RestorePythonException& e) {
|
|
1583
|
-
e.restore();
|
|
1470
|
+
auto private_name_result = custom_random_string(type_id, name, type_need_call);
|
|
1471
|
+
if (!private_name_result.ok) {
|
|
1584
1472
|
return -2; // -2 means exception
|
|
1585
1473
|
}
|
|
1474
|
+
key = private_name_result.value;
|
|
1586
1475
|
} else {
|
|
1587
1476
|
key = default_random_string(type_id, name);
|
|
1588
1477
|
}
|
|
@@ -1616,12 +1505,11 @@ type_get_final_attr(uintptr_t type_id, const std::string& name) noexcept
|
|
|
1616
1505
|
if (::AllData::type_need_call.find(now_visited_id) != ::AllData::type_need_call.end()) {
|
|
1617
1506
|
PyObject* func = ::AllData::type_need_call[now_visited_id];
|
|
1618
1507
|
if (func != NULL) {
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
} catch (RestorePythonException& e) {
|
|
1622
|
-
e.restore();
|
|
1508
|
+
auto private_name_result = custom_random_string(now_visited_id, name, func);
|
|
1509
|
+
if (!private_name_result.ok) {
|
|
1623
1510
|
return -2; // -2 means exception
|
|
1624
1511
|
}
|
|
1512
|
+
key = private_name_result.value;
|
|
1625
1513
|
} else {
|
|
1626
1514
|
key = default_random_string(now_visited_id, name);
|
|
1627
1515
|
}
|
|
@@ -1647,12 +1535,11 @@ type_get_final_attr(uintptr_t type_id, const std::string& name) noexcept
|
|
|
1647
1535
|
if (::AllData::type_need_call.find(parent_id) != ::AllData::type_need_call.end()) {
|
|
1648
1536
|
PyObject* func = ::AllData::type_need_call[parent_id];
|
|
1649
1537
|
if (func != NULL) {
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
} catch (RestorePythonException& e) {
|
|
1653
|
-
e.restore();
|
|
1538
|
+
auto private_name_result = custom_random_string(parent_id, name, func);
|
|
1539
|
+
if (!private_name_result.ok) {
|
|
1654
1540
|
return -2; // -2 means exception
|
|
1655
1541
|
}
|
|
1542
|
+
key = private_name_result.value;
|
|
1656
1543
|
} else {
|
|
1657
1544
|
key = default_random_string(parent_id, name);
|
|
1658
1545
|
}
|
|
@@ -1975,7 +1862,7 @@ PrivateAttrType_preprocess(PyObject* args, PyObject* kwds, PrivateAttrCreationDa
|
|
|
1975
1862
|
return false;
|
|
1976
1863
|
}
|
|
1977
1864
|
|
|
1978
|
-
if (!
|
|
1865
|
+
if (!PyAnyDict_Check(data.attrs)) {
|
|
1979
1866
|
PyErr_SetString(PyExc_TypeError, "attrs must be a dict");
|
|
1980
1867
|
return false;
|
|
1981
1868
|
}
|
|
@@ -2312,12 +2199,11 @@ PrivateAttrType_postprocess(PyObject* new_type, PrivateAttrCreationData& data) n
|
|
|
2312
2199
|
for (auto& [key, value]: data.need_remove_itself) {
|
|
2313
2200
|
std::string final_key;
|
|
2314
2201
|
if (data.private_func) {
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
} catch (RestorePythonException& e) {
|
|
2318
|
-
e.restore();
|
|
2202
|
+
auto private_name_result = custom_random_string(type_id, key, data.private_func);
|
|
2203
|
+
if (!private_name_result.ok) {
|
|
2319
2204
|
return false;
|
|
2320
2205
|
}
|
|
2206
|
+
final_key = private_name_result.value;
|
|
2321
2207
|
} else {
|
|
2322
2208
|
final_key = default_random_string(type_id, key);
|
|
2323
2209
|
}
|
|
@@ -2341,12 +2227,11 @@ PrivateAttrType_postprocess(PyObject* new_type, PrivateAttrCreationData& data) n
|
|
|
2341
2227
|
for (auto& [key, value]: map) {
|
|
2342
2228
|
std::string final_key;
|
|
2343
2229
|
if (data.private_func) {
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
} catch (RestorePythonException& e) {
|
|
2347
|
-
e.restore();
|
|
2230
|
+
auto private_name_result = custom_random_string(type_id, key, data.private_func);
|
|
2231
|
+
if (!private_name_result.ok) {
|
|
2348
2232
|
return false;
|
|
2349
2233
|
}
|
|
2234
|
+
final_key = private_name_result.value;
|
|
2350
2235
|
} else {
|
|
2351
2236
|
final_key = default_random_string(type_id, key);
|
|
2352
2237
|
}
|
|
@@ -2505,7 +2390,9 @@ init_all_slots() noexcept
|
|
|
2505
2390
|
for (Py_ssize_t i = 0; i < list_len; i++) {
|
|
2506
2391
|
PyObject* metaclass = PyList_GET_ITEM(all_metaclasses, i);
|
|
2507
2392
|
if (!PyType_Check(metaclass)) {continue;}
|
|
2508
|
-
((PyTypeObject*)metaclass)->tp_setattro
|
|
2393
|
+
if (((PyTypeObject*)metaclass)->tp_setattro == original_type_tp_setattro) {
|
|
2394
|
+
((PyTypeObject*)metaclass)->tp_setattro = new_type_tp_setattro;
|
|
2395
|
+
}
|
|
2509
2396
|
}
|
|
2510
2397
|
Py_DECREF(all_metaclasses);
|
|
2511
2398
|
return 0;
|
|
@@ -3134,7 +3021,7 @@ PrivateModule_setattro(PyObject* self, PyObject* name, PyObject* value) noexcept
|
|
|
3134
3021
|
const size_t num_attrs = sizeof(unsetable_attrs) / sizeof(unsetable_attrs[0]);
|
|
3135
3022
|
for (size_t i = 0; i < num_attrs; ++i) {
|
|
3136
3023
|
if (strcmp(name_cstr, unsetable_attrs[i]) == 0) {
|
|
3137
|
-
PyErr_Format(PyExc_AttributeError, "attribute '%s' of 'private_attribute_module' objects is not writable", name_cstr);
|
|
3024
|
+
PyErr_Format(PyExc_AttributeError, "attribute '%s' of 'private_attribute.private_attribute_module' objects is not writable", name_cstr);
|
|
3138
3025
|
return -1;
|
|
3139
3026
|
}
|
|
3140
3027
|
}
|
|
@@ -3294,8 +3181,8 @@ static PyTypeObject PrivateModuleType = {
|
|
|
3294
3181
|
|
|
3295
3182
|
static const char* module_doc = R"(
|
|
3296
3183
|
A module that provides a metaclass for creating classes with private attributes.
|
|
3297
|
-
Private attributes are defined in the `__private_attrs__` sequence and are only
|
|
3298
|
-
You can use the `PrivateAttrBase`
|
|
3184
|
+
Private attributes are defined in the `__private_attrs__` sequence and are only visitable in class codes.
|
|
3185
|
+
You can use the `PrivateAttrBase` as the base class to create classes with private attributes.
|
|
3299
3186
|
The attributes which are private are not on the instance's `__dict__` and cannot be accessed outside
|
|
3300
3187
|
but in the methods defined in class it is reachable.
|
|
3301
3188
|
Usage example:
|
{private_attribute_cpp-2.0.0 → private_attribute_cpp-2.0.2/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.2
|
|
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.2',
|
|
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.0 → private_attribute_cpp-2.0.2}/tests/test_class_private_attrs.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{private_attribute_cpp-2.0.0 → private_attribute_cpp-2.0.2}/tests/test_private_inheritance.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|