pyobject 1.3.2__tar.gz → 1.3.4__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.
- {pyobject-1.3.2 → pyobject-1.3.4}/LICENSE +21 -21
- pyobject-1.3.4/MANIFEST.in +3 -0
- {pyobject-1.3.2/pyobject.egg-info → pyobject-1.3.4}/PKG-INFO +60 -37
- {pyobject-1.3.2 → pyobject-1.3.4}/README.rst +44 -31
- pyobject-1.3.4/pyobject/__init__.py +145 -0
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/browser.py +8 -19
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/code.py +7 -6
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/objproxy/__init__.py +2 -1
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/pyobj_extension.c +48 -42
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/search.py +1 -1
- {pyobject-1.3.2 → pyobject-1.3.4/pyobject.egg-info}/PKG-INFO +60 -37
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject.egg-info/SOURCES.txt +0 -7
- {pyobject-1.3.2 → pyobject-1.3.4}/setup.py +3 -3
- pyobject-1.3.2/MANIFEST.in +0 -5
- pyobject-1.3.2/pyobject/__init__.py +0 -113
- pyobject-1.3.2/pyobject/examples/README.md +0 -7
- pyobject-1.3.2/pyobject/examples/__init__.py +0 -1
- pyobject-1.3.2/pyobject/examples/empty_cp37.pyc +0 -0
- pyobject-1.3.2/pyobject/examples/pyc_zipper_unpack.py +0 -55
- pyobject-1.3.2/pyobject/examples/pyc_zipper_zlib.py +0 -58
- pyobject-1.3.2/pyobject/examples/test_inject.py +0 -134
- pyobject-1.3.2/pyobject/other/browser_chs_locale.py +0 -489
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/back.gif +0 -0
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/codeobject.gif +0 -0
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/dict.gif +0 -0
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/empty_dict.gif +0 -0
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/empty_list.gif +0 -0
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/empty_tuple.gif +0 -0
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/forward.gif +0 -0
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/function.gif +0 -0
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/list.gif +0 -0
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/number.gif +0 -0
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/python.gif +0 -0
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/python.ico +0 -0
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/refresh.gif +0 -0
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/string.gif +0 -0
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/tuple.gif +0 -0
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/objproxy/builtin_hook.py +0 -0
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/objproxy/optimize.py +0 -0
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/objproxy/utils.py +0 -0
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/tests/test_code.py +0 -0
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/tests/test_objproxy.py +0 -0
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/tests/test_objproxy_perf.py +0 -0
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject.egg-info/dependency_links.txt +0 -0
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject.egg-info/requires.txt +0 -0
- {pyobject-1.3.2 → pyobject-1.3.4}/pyobject.egg-info/top_level.txt +0 -0
- {pyobject-1.3.2 → pyobject-1.3.4}/setup.cfg +0 -0
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c)
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ekcbw
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: pyobject
|
|
3
|
-
Version: 1.3.
|
|
4
|
-
Summary: A multifunctional all-in-one utility tool for managing internal Python objects, compatible with nearly all Python 3 versions.
|
|
5
|
-
Home-page: https://github.com/
|
|
6
|
-
Author:
|
|
7
|
-
Author-email:
|
|
3
|
+
Version: 1.3.4
|
|
4
|
+
Summary: A multifunctional all-in-one utility tool for managing internal Python objects, compatible with nearly all Python 3 versions.
|
|
5
|
+
Home-page: https://github.com/ekcbw/pyobject
|
|
6
|
+
Author: ekcbw
|
|
7
|
+
Author-email: u81430728@163.com
|
|
8
8
|
Keywords: pyobject,python,object,utility,object browser,bytecode,reflect,object search,OOP,reverse,对象,字节码,逆向
|
|
9
9
|
Classifier: Programming Language :: Python
|
|
10
10
|
Classifier: Topic :: Utilities
|
|
@@ -14,11 +14,22 @@ Classifier: Topic :: Software Development :: Object Brokering
|
|
|
14
14
|
Classifier: Topic :: Software Development :: Testing
|
|
15
15
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
16
16
|
License-File: LICENSE
|
|
17
|
+
Requires-Dist: astor; python_version <= "3.8"
|
|
18
|
+
Dynamic: author
|
|
19
|
+
Dynamic: author-email
|
|
20
|
+
Dynamic: classifier
|
|
21
|
+
Dynamic: description
|
|
22
|
+
Dynamic: home-page
|
|
23
|
+
Dynamic: keywords
|
|
24
|
+
Dynamic: license-file
|
|
25
|
+
Dynamic: provides-extra
|
|
26
|
+
Dynamic: summary
|
|
17
27
|
|
|
18
28
|
|Stars| |GitHub release| |License: MIT|
|
|
19
29
|
|
|
20
30
|
pyobject - A multifunctional all-in-one utility tool for managing
|
|
21
|
-
internal Python objects, compatible with nearly all Python 3 versions
|
|
31
|
+
internal Python objects, compatible with nearly all Python 3 versions
|
|
32
|
+
and all platforms (Windows, Linux, macOS, etc.).
|
|
22
33
|
|
|
23
34
|
[English \| `中文 <README_zh.md>`__]
|
|
24
35
|
|
|
@@ -52,21 +63,23 @@ file=sys.stdout)**:
|
|
|
52
63
|
for debugging purpose. The alias is ``desc()``.
|
|
53
64
|
| - maxlevel: The depth of attribute levels to print. - tab: Number of
|
|
54
65
|
spaces for indentation, default is 4. - verbose: Boolean indicating
|
|
55
|
-
whether to print special methods (e.g., ``__init__``). -
|
|
66
|
+
whether to print special methods (e.g., ``__init__``). - maxlength:
|
|
67
|
+
The maximum output length of one object. - ignore_funcs: If set to
|
|
68
|
+
True, methods or functions of the object will not be output. - file: A
|
|
56
69
|
file-like object for output.
|
|
57
70
|
|
|
58
71
|
**browse(object, verbose=False, name=‘obj’)**:
|
|
59
72
|
|
|
60
|
-
Browse any Python objects in a
|
|
61
|
-
|
|
73
|
+
Browse any Python objects in a GUI using tkinter. - verbose: Same as in
|
|
74
|
+
``describe()``, whether to print special methods.
|
|
62
75
|
|
|
63
|
-
The
|
|
76
|
+
The GUI of browse() function is:
|
|
64
77
|
|
|
65
78
|
.. figure::
|
|
66
|
-
https://i-blog.csdnimg.cn/direct/
|
|
67
|
-
:alt:
|
|
79
|
+
https://i-blog.csdnimg.cn/direct/a4d513de3c234ef29b382c026b2bac20.png
|
|
80
|
+
:alt: GUI of browse()
|
|
68
81
|
|
|
69
|
-
|
|
82
|
+
GUI of browse()
|
|
70
83
|
|
|
71
84
|
**bases(obj, level=0, tab=4)**:
|
|
72
85
|
|
|
@@ -99,8 +112,8 @@ strings.
|
|
|
99
112
|
Class: ``pyobject.Code``
|
|
100
113
|
------------------------
|
|
101
114
|
|
|
102
|
-
The ``Code`` class provides a wrapper for Python bytecode objects
|
|
103
|
-
|
|
115
|
+
The ``Code`` class provides a wrapper for Python bytecode objects to
|
|
116
|
+
manipulate them.
|
|
104
117
|
|
|
105
118
|
Python’s internal bytecode object, ``CodeType`` (e.g.,
|
|
106
119
|
``func.__code__``), is immutable. The ``Code`` class offers a
|
|
@@ -112,7 +125,7 @@ compatible**. Bytecode generated by different versions of the Python
|
|
|
112
125
|
interpreter is incompatible.
|
|
113
126
|
|
|
114
127
|
The ``Code`` class provides a **universal interface** for bytecode,
|
|
115
|
-
supporting all Python versions from **3.
|
|
128
|
+
supporting all Python versions from **3.6 to 3.14** (including PyPy’s
|
|
116
129
|
``.pyc`` format), simplifying complex version compatibility issues.
|
|
117
130
|
|
|
118
131
|
Constructor (``def __init__(self, code=None)``)
|
|
@@ -463,13 +476,13 @@ Increases the reference count of an object.
|
|
|
463
476
|
|
|
464
477
|
| Get the actual reference count of the object before calling this
|
|
465
478
|
function.
|
|
466
|
-
| Unlike sys.getrefcount()
|
|
479
|
+
| Unlike ``sys.getrefcount()``, this function does not consider the
|
|
467
480
|
additional reference count that is created when the function is
|
|
468
481
|
called. (The difference is the constant ``_REFCNT_DELTA``)
|
|
469
|
-
| For example, getrealrefcount([]) will return 0,
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
| Additionally, a=[]; getrealrefcount(a) will return 1 instead of 2.
|
|
482
|
+
| For example, ``getrealrefcount([])`` will return 0, since after the
|
|
483
|
+
call finishes, ``[]`` will never be referenced by any objects, whereas
|
|
484
|
+
``sys.getrefcount([])`` will return 1.
|
|
485
|
+
| Additionally, ``a=[]; getrealrefcount(a)`` will return 1 instead of 2.
|
|
473
486
|
|
|
474
487
|
**setrefcount(obj, n)**:
|
|
475
488
|
|
|
@@ -480,24 +493,34 @@ Increases the reference count of an object.
|
|
|
480
493
|
|
|
481
494
|
**getrefcount_nogil(obj)** and **setrefcount_nogil(obj, ref_data)**:
|
|
482
495
|
|
|
483
|
-
In the GIL-free version of Python 3.
|
|
496
|
+
In the GIL-free version of Python 3.13+, get and set reference counts,
|
|
484
497
|
where ``ref_data`` is ``(ob_ref_local, ob_ref_shared)``, without
|
|
485
|
-
considering the reference counts added during the call.
|
|
498
|
+
considering the reference counts added during the call.
|
|
486
499
|
|
|
487
|
-
*Warning: Improper use of these functions above may lead to
|
|
500
|
+
*Warning: Improper use of these functions above may lead to crash of the
|
|
501
|
+
intepreter.*
|
|
488
502
|
|
|
489
503
|
**list_in(obj, lst)**:
|
|
490
504
|
|
|
491
505
|
Determine whether obj is in the sequence lst. Compared to the built-in
|
|
492
|
-
Python call
|
|
493
|
-
multiple times, this function directly compares the
|
|
494
|
-
|
|
506
|
+
Python call ``obj in lst`` that invokes the ``==`` operator
|
|
507
|
+
(``__eq__()``) multiple times, this function directly compares the
|
|
508
|
+
pointers to improve the performance.
|
|
495
509
|
|
|
496
|
-
**
|
|
510
|
+
**get_string_intern_dict()**:
|
|
511
|
+
|
|
512
|
+
Return the internal dictionary for interning strings (``sys.intern()``).
|
|
513
|
+
|
|
514
|
+
**Current ``pyobject`` Version**: 1.3.4
|
|
497
515
|
|
|
498
516
|
Change Log
|
|
499
517
|
----------
|
|
500
518
|
|
|
519
|
+
| 2026-1-22(v1.3.4): Added ``get_string_intern_dict()`` to
|
|
520
|
+
``pyobject.pyobj_extension`` module (available for 3.12+).
|
|
521
|
+
| 2026-1-4(v1.3.3): Improved the support for Python 3.14 and
|
|
522
|
+
``describe()`` function. Adjusted the minimum supported Python version
|
|
523
|
+
to 3.6.
|
|
501
524
|
| 2025-6-23(v1.3.2): Added the ``use_exported_obj`` parameter to the
|
|
502
525
|
pyobject.objproxy module and further optimized the performance.
|
|
503
526
|
| 2025-6-6(v1.3.0): Optimized the performance of the pyobject.objproxy
|
|
@@ -519,8 +542,8 @@ Change Log
|
|
|
519
542
|
| 2024-10-24 (v1.2.5): Fixed high DPI support for ``pyobject.browser``
|
|
520
543
|
on Windows, modified the ``pyobj_extension`` module, along with other
|
|
521
544
|
improvements.
|
|
522
|
-
| 2024-08-12 (v1.2.4): Added support for Python
|
|
523
|
-
|
|
545
|
+
| 2024-08-12 (v1.2.4): Added support for Python 3.10 and above in
|
|
546
|
+
``pyobject.code_``; further optimized search performance in the
|
|
524
547
|
``search`` module, along with various other fixes and improvements.
|
|
525
548
|
| 2024-06-20 (v1.2.3): Updated the ``.pyc`` file packing tool in the
|
|
526
549
|
``test`` directory of the package, and enhanced the object browser in
|
|
@@ -535,9 +558,9 @@ Change Log
|
|
|
535
558
|
introduced editing properties functionality in ``browser``, and added
|
|
536
559
|
doctests for the ``Code`` class.
|
|
537
560
|
|
|
538
|
-
.. |Stars| image:: https://img.shields.io/github/stars/
|
|
539
|
-
:target: https://img.shields.io/github/stars/
|
|
540
|
-
.. |GitHub release| image:: https://img.shields.io/github/v/release/
|
|
541
|
-
:target: https://github.com/
|
|
542
|
-
.. |License: MIT| image:: https://img.shields.io/github/license/
|
|
543
|
-
:target: https://github.com/
|
|
561
|
+
.. |Stars| image:: https://img.shields.io/github/stars/ekcbw/pyobject
|
|
562
|
+
:target: https://img.shields.io/github/stars/ekcbw/pyobject
|
|
563
|
+
.. |GitHub release| image:: https://img.shields.io/github/v/release/ekcbw/pyobject
|
|
564
|
+
:target: https://github.com/ekcbw/pyobject/releases/latest
|
|
565
|
+
.. |License: MIT| image:: https://img.shields.io/github/license/ekcbw/pyobject
|
|
566
|
+
:target: https://github.com/ekcbw/pyobject/blob/main/LICENSE
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
|Stars| |GitHub release| |License: MIT|
|
|
2
2
|
|
|
3
3
|
pyobject - A multifunctional all-in-one utility tool for managing
|
|
4
|
-
internal Python objects, compatible with nearly all Python 3 versions
|
|
4
|
+
internal Python objects, compatible with nearly all Python 3 versions
|
|
5
|
+
and all platforms (Windows, Linux, macOS, etc.).
|
|
5
6
|
|
|
6
7
|
[English \| `中文 <README_zh.md>`__]
|
|
7
8
|
|
|
@@ -35,21 +36,23 @@ file=sys.stdout)**:
|
|
|
35
36
|
for debugging purpose. The alias is ``desc()``.
|
|
36
37
|
| - maxlevel: The depth of attribute levels to print. - tab: Number of
|
|
37
38
|
spaces for indentation, default is 4. - verbose: Boolean indicating
|
|
38
|
-
whether to print special methods (e.g., ``__init__``). -
|
|
39
|
+
whether to print special methods (e.g., ``__init__``). - maxlength:
|
|
40
|
+
The maximum output length of one object. - ignore_funcs: If set to
|
|
41
|
+
True, methods or functions of the object will not be output. - file: A
|
|
39
42
|
file-like object for output.
|
|
40
43
|
|
|
41
44
|
**browse(object, verbose=False, name=‘obj’)**:
|
|
42
45
|
|
|
43
|
-
Browse any Python objects in a
|
|
44
|
-
|
|
46
|
+
Browse any Python objects in a GUI using tkinter. - verbose: Same as in
|
|
47
|
+
``describe()``, whether to print special methods.
|
|
45
48
|
|
|
46
|
-
The
|
|
49
|
+
The GUI of browse() function is:
|
|
47
50
|
|
|
48
51
|
.. figure::
|
|
49
|
-
https://i-blog.csdnimg.cn/direct/
|
|
50
|
-
:alt:
|
|
52
|
+
https://i-blog.csdnimg.cn/direct/a4d513de3c234ef29b382c026b2bac20.png
|
|
53
|
+
:alt: GUI of browse()
|
|
51
54
|
|
|
52
|
-
|
|
55
|
+
GUI of browse()
|
|
53
56
|
|
|
54
57
|
**bases(obj, level=0, tab=4)**:
|
|
55
58
|
|
|
@@ -82,8 +85,8 @@ strings.
|
|
|
82
85
|
Class: ``pyobject.Code``
|
|
83
86
|
------------------------
|
|
84
87
|
|
|
85
|
-
The ``Code`` class provides a wrapper for Python bytecode objects
|
|
86
|
-
|
|
88
|
+
The ``Code`` class provides a wrapper for Python bytecode objects to
|
|
89
|
+
manipulate them.
|
|
87
90
|
|
|
88
91
|
Python’s internal bytecode object, ``CodeType`` (e.g.,
|
|
89
92
|
``func.__code__``), is immutable. The ``Code`` class offers a
|
|
@@ -95,7 +98,7 @@ compatible**. Bytecode generated by different versions of the Python
|
|
|
95
98
|
interpreter is incompatible.
|
|
96
99
|
|
|
97
100
|
The ``Code`` class provides a **universal interface** for bytecode,
|
|
98
|
-
supporting all Python versions from **3.
|
|
101
|
+
supporting all Python versions from **3.6 to 3.14** (including PyPy’s
|
|
99
102
|
``.pyc`` format), simplifying complex version compatibility issues.
|
|
100
103
|
|
|
101
104
|
Constructor (``def __init__(self, code=None)``)
|
|
@@ -446,13 +449,13 @@ Increases the reference count of an object.
|
|
|
446
449
|
|
|
447
450
|
| Get the actual reference count of the object before calling this
|
|
448
451
|
function.
|
|
449
|
-
| Unlike sys.getrefcount()
|
|
452
|
+
| Unlike ``sys.getrefcount()``, this function does not consider the
|
|
450
453
|
additional reference count that is created when the function is
|
|
451
454
|
called. (The difference is the constant ``_REFCNT_DELTA``)
|
|
452
|
-
| For example, getrealrefcount([]) will return 0,
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
| Additionally, a=[]; getrealrefcount(a) will return 1 instead of 2.
|
|
455
|
+
| For example, ``getrealrefcount([])`` will return 0, since after the
|
|
456
|
+
call finishes, ``[]`` will never be referenced by any objects, whereas
|
|
457
|
+
``sys.getrefcount([])`` will return 1.
|
|
458
|
+
| Additionally, ``a=[]; getrealrefcount(a)`` will return 1 instead of 2.
|
|
456
459
|
|
|
457
460
|
**setrefcount(obj, n)**:
|
|
458
461
|
|
|
@@ -463,24 +466,34 @@ Increases the reference count of an object.
|
|
|
463
466
|
|
|
464
467
|
**getrefcount_nogil(obj)** and **setrefcount_nogil(obj, ref_data)**:
|
|
465
468
|
|
|
466
|
-
In the GIL-free version of Python 3.
|
|
469
|
+
In the GIL-free version of Python 3.13+, get and set reference counts,
|
|
467
470
|
where ``ref_data`` is ``(ob_ref_local, ob_ref_shared)``, without
|
|
468
|
-
considering the reference counts added during the call.
|
|
471
|
+
considering the reference counts added during the call.
|
|
469
472
|
|
|
470
|
-
*Warning: Improper use of these functions above may lead to
|
|
473
|
+
*Warning: Improper use of these functions above may lead to crash of the
|
|
474
|
+
intepreter.*
|
|
471
475
|
|
|
472
476
|
**list_in(obj, lst)**:
|
|
473
477
|
|
|
474
478
|
Determine whether obj is in the sequence lst. Compared to the built-in
|
|
475
|
-
Python call
|
|
476
|
-
multiple times, this function directly compares the
|
|
477
|
-
|
|
479
|
+
Python call ``obj in lst`` that invokes the ``==`` operator
|
|
480
|
+
(``__eq__()``) multiple times, this function directly compares the
|
|
481
|
+
pointers to improve the performance.
|
|
478
482
|
|
|
479
|
-
**
|
|
483
|
+
**get_string_intern_dict()**:
|
|
484
|
+
|
|
485
|
+
Return the internal dictionary for interning strings (``sys.intern()``).
|
|
486
|
+
|
|
487
|
+
**Current ``pyobject`` Version**: 1.3.4
|
|
480
488
|
|
|
481
489
|
Change Log
|
|
482
490
|
----------
|
|
483
491
|
|
|
492
|
+
| 2026-1-22(v1.3.4): Added ``get_string_intern_dict()`` to
|
|
493
|
+
``pyobject.pyobj_extension`` module (available for 3.12+).
|
|
494
|
+
| 2026-1-4(v1.3.3): Improved the support for Python 3.14 and
|
|
495
|
+
``describe()`` function. Adjusted the minimum supported Python version
|
|
496
|
+
to 3.6.
|
|
484
497
|
| 2025-6-23(v1.3.2): Added the ``use_exported_obj`` parameter to the
|
|
485
498
|
pyobject.objproxy module and further optimized the performance.
|
|
486
499
|
| 2025-6-6(v1.3.0): Optimized the performance of the pyobject.objproxy
|
|
@@ -502,8 +515,8 @@ Change Log
|
|
|
502
515
|
| 2024-10-24 (v1.2.5): Fixed high DPI support for ``pyobject.browser``
|
|
503
516
|
on Windows, modified the ``pyobj_extension`` module, along with other
|
|
504
517
|
improvements.
|
|
505
|
-
| 2024-08-12 (v1.2.4): Added support for Python
|
|
506
|
-
|
|
518
|
+
| 2024-08-12 (v1.2.4): Added support for Python 3.10 and above in
|
|
519
|
+
``pyobject.code_``; further optimized search performance in the
|
|
507
520
|
``search`` module, along with various other fixes and improvements.
|
|
508
521
|
| 2024-06-20 (v1.2.3): Updated the ``.pyc`` file packing tool in the
|
|
509
522
|
``test`` directory of the package, and enhanced the object browser in
|
|
@@ -518,9 +531,9 @@ Change Log
|
|
|
518
531
|
introduced editing properties functionality in ``browser``, and added
|
|
519
532
|
doctests for the ``Code`` class.
|
|
520
533
|
|
|
521
|
-
.. |Stars| image:: https://img.shields.io/github/stars/
|
|
522
|
-
:target: https://img.shields.io/github/stars/
|
|
523
|
-
.. |GitHub release| image:: https://img.shields.io/github/v/release/
|
|
524
|
-
:target: https://github.com/
|
|
525
|
-
.. |License: MIT| image:: https://img.shields.io/github/license/
|
|
526
|
-
:target: https://github.com/
|
|
534
|
+
.. |Stars| image:: https://img.shields.io/github/stars/ekcbw/pyobject
|
|
535
|
+
:target: https://img.shields.io/github/stars/ekcbw/pyobject
|
|
536
|
+
.. |GitHub release| image:: https://img.shields.io/github/v/release/ekcbw/pyobject
|
|
537
|
+
:target: https://github.com/ekcbw/pyobject/releases/latest
|
|
538
|
+
.. |License: MIT| image:: https://img.shields.io/github/license/ekcbw/pyobject
|
|
539
|
+
:target: https://github.com/ekcbw/pyobject/blob/main/LICENSE
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"""A multifunctional all-in-one utility tool for managing internal Python \
|
|
2
|
+
objects, compatible with nearly all Python 3 versions.
|
|
3
|
+
"""
|
|
4
|
+
import sys, types
|
|
5
|
+
from warnings import warn
|
|
6
|
+
from pprint import pprint
|
|
7
|
+
from inspect import isfunction,ismethod
|
|
8
|
+
try:
|
|
9
|
+
from types import WrapperDescriptorType,MethodWrapperType,\
|
|
10
|
+
MethodDescriptorType,ClassMethodDescriptorType
|
|
11
|
+
except ImportError: # 低于3.7的版本
|
|
12
|
+
from typing import WrapperDescriptorType,MethodWrapperType,\
|
|
13
|
+
MethodDescriptorType
|
|
14
|
+
ClassMethodDescriptorType = type(dict.__dict__['fromkeys'])
|
|
15
|
+
|
|
16
|
+
__version__="1.3.4"
|
|
17
|
+
|
|
18
|
+
__all__=["objectname","bases","describe","desc"]
|
|
19
|
+
_always_ignored_names=["__builtins__","__doc__"]
|
|
20
|
+
|
|
21
|
+
MAXLENGTH=150
|
|
22
|
+
|
|
23
|
+
def isfunc(obj):
|
|
24
|
+
# 判断一个对象是否为函数或方法
|
|
25
|
+
if isfunction(obj) or ismethod(obj):return True
|
|
26
|
+
# 使用typing而不用types.WrapperDescriptorType是为了与旧版本兼容
|
|
27
|
+
func_types=[types.LambdaType,types.BuiltinFunctionType,
|
|
28
|
+
types.BuiltinMethodType,WrapperDescriptorType,
|
|
29
|
+
MethodWrapperType,MethodDescriptorType,
|
|
30
|
+
ClassMethodDescriptorType]
|
|
31
|
+
for type_ in func_types:
|
|
32
|
+
if isinstance(obj,type_):
|
|
33
|
+
return True
|
|
34
|
+
return False
|
|
35
|
+
|
|
36
|
+
def objectname(obj):
|
|
37
|
+
# 返回对象的全名,类似__qualname__属性
|
|
38
|
+
# if hasattr(obj,"__qualname__"):return obj.__qualname__
|
|
39
|
+
if not obj.__class__==type:obj=obj.__class__
|
|
40
|
+
if not hasattr(obj,"__module__") or obj.__module__=="__main__":
|
|
41
|
+
return obj.__name__
|
|
42
|
+
return "{}.{}".format(obj.__module__,obj.__name__)
|
|
43
|
+
|
|
44
|
+
def bases(obj,level=0,tab=4):
|
|
45
|
+
# 打印对象的基类
|
|
46
|
+
if not obj.__class__==type:obj=obj.__class__
|
|
47
|
+
if obj.__bases__:
|
|
48
|
+
if level:print(' '*(level*tab),end='')
|
|
49
|
+
print(*obj.__bases__,sep=',')
|
|
50
|
+
for cls in obj.__bases__:
|
|
51
|
+
bases(cls,level,tab)
|
|
52
|
+
|
|
53
|
+
_trans_table=str.maketrans("\n\t"," ") # 替换特殊字符为空格
|
|
54
|
+
def shortrepr(obj,maxlength=None,repr_func=None):
|
|
55
|
+
if repr_func is None:repr_func = repr
|
|
56
|
+
if maxlength is None:maxlength = MAXLENGTH
|
|
57
|
+
result=repr_func(obj).translate(_trans_table)
|
|
58
|
+
if len(result)>maxlength:
|
|
59
|
+
return result[:maxlength]+"..."
|
|
60
|
+
return result
|
|
61
|
+
|
|
62
|
+
def describe(obj,level=0,maxlevel=1,tab=4,verbose=False,file=None,
|
|
63
|
+
maxlength=None,ignore_funcs=False):
|
|
64
|
+
'''"Describe" an object by printing its attributes.
|
|
65
|
+
Parameters:
|
|
66
|
+
maxlevel: The number of levels to print the object's attributes.
|
|
67
|
+
tab: The number of spaces for indentation, default is 4.
|
|
68
|
+
verbose: Whether to output attributes starting with "_" (e.g., __init__).
|
|
69
|
+
maxlength: The maximum output length of one object.
|
|
70
|
+
ignore_funcs: If set to True, methods or functions of the object will not be output.
|
|
71
|
+
file: A file-like object for printing output.
|
|
72
|
+
'''
|
|
73
|
+
if file is None:file=sys.stdout
|
|
74
|
+
if level==maxlevel:
|
|
75
|
+
result=repr(obj)
|
|
76
|
+
if result.startswith('[') or result.startswith('{'):pprint(result)
|
|
77
|
+
else:print(result,file=file)
|
|
78
|
+
elif level>maxlevel:
|
|
79
|
+
raise ValueError("Argument level is larger than maxlevel")
|
|
80
|
+
else:
|
|
81
|
+
print(shortrepr(obj,maxlength)+': ',file=file)
|
|
82
|
+
if type(obj) is type:
|
|
83
|
+
print("Base classes of the object:",file=file)
|
|
84
|
+
bases(obj,level+1,tab)
|
|
85
|
+
print(file=file)
|
|
86
|
+
for attr in dir(obj):
|
|
87
|
+
if verbose or not attr.startswith("_"):
|
|
88
|
+
print(' '*tab*(level+1),end='',file=file)
|
|
89
|
+
try:
|
|
90
|
+
value = getattr(obj,attr)
|
|
91
|
+
if ignore_funcs and isfunc(value):
|
|
92
|
+
continue
|
|
93
|
+
print(f"{attr}: ",file=file)
|
|
94
|
+
if attr in _always_ignored_names:
|
|
95
|
+
describe(value,level+1,maxlevel,tab,verbose,file,maxlength)
|
|
96
|
+
else:
|
|
97
|
+
print(shortrepr(value,maxlength),file=file)
|
|
98
|
+
except AttributeError:
|
|
99
|
+
print(f"{attr}: <AttributeError!>",file=file)
|
|
100
|
+
if isinstance(obj, list):
|
|
101
|
+
print("\nList items of the object:",file=file)
|
|
102
|
+
for i,item in enumerate(obj):
|
|
103
|
+
print(f"{' '*tab*(level+1)}{i}: ",end='',file=file)
|
|
104
|
+
describe(item,level+1,maxlevel,tab,verbose,file,maxlength)
|
|
105
|
+
if isinstance(obj, dict):
|
|
106
|
+
print("\nDictionary items of the object:",file=file)
|
|
107
|
+
for key in obj.keys():
|
|
108
|
+
print(f"{' '*tab*(level+1)}{key!r}: ",end='',file=file)
|
|
109
|
+
try:
|
|
110
|
+
describe(obj[key],level+1,maxlevel,tab,verbose,file,maxlength)
|
|
111
|
+
except KeyError:
|
|
112
|
+
print("<KeyError!>",file=file)
|
|
113
|
+
|
|
114
|
+
desc = describe #别名
|
|
115
|
+
|
|
116
|
+
# 导入其他子模块中的函数和类
|
|
117
|
+
try:
|
|
118
|
+
from pyobject.browser import browse
|
|
119
|
+
__all__.append("browse")
|
|
120
|
+
except ImportError:warn("Failed to import module pyobject.browser.")
|
|
121
|
+
try:
|
|
122
|
+
from pyobject.search import make_list,make_iter,search
|
|
123
|
+
__all__.extend(["make_list","make_iter","search"])
|
|
124
|
+
except ImportError:warn("Failed to import pyobject.search.")
|
|
125
|
+
|
|
126
|
+
try:
|
|
127
|
+
from pyobject.code import Code
|
|
128
|
+
__all__.append("Code")
|
|
129
|
+
except ImportError:warn("Failed to import pyobject.code.")
|
|
130
|
+
try:
|
|
131
|
+
from pyobject.pyobj_extension import *
|
|
132
|
+
__all__.extend(["convptr","py_incref","py_decref","getrealrefcount",
|
|
133
|
+
"setrefcount","list_in","getrefcount_nogil","setrefcount_nogil",
|
|
134
|
+
"get_type_flag","set_type_flag","set_type_base","set_type_bases",
|
|
135
|
+
"set_type_mro","get_type_subclasses","set_type_subclasses",
|
|
136
|
+
"set_type_subclasses_by_cls","get_string_intern_dict"])
|
|
137
|
+
except ImportError:warn("Failed to import pyobject.pyobj_extension.")
|
|
138
|
+
try:
|
|
139
|
+
from pyobject.objproxy import ObjChain,ProxiedObj,unproxy_obj
|
|
140
|
+
__all__.extend(["ObjChain","ProxiedObj","unproxy_obj"])
|
|
141
|
+
except ImportError as err:
|
|
142
|
+
warn("Failed to import pyobject.objproxy (%s): %s"%(type(err).__name__,err))
|
|
143
|
+
|
|
144
|
+
if __name__=="__main__":
|
|
145
|
+
describe(type,verbose=True)
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
"
|
|
2
|
-
import sys,os,types,
|
|
1
|
+
"A module providing a visual interface to browse Python objects."
|
|
2
|
+
import sys,os,types,ctypes
|
|
3
3
|
import tkinter as tk
|
|
4
4
|
import tkinter.ttk as ttk
|
|
5
5
|
import tkinter.messagebox as msgbox
|
|
6
6
|
import tkinter.simpledialog as simpledialog
|
|
7
|
-
from inspect import
|
|
7
|
+
from inspect import iscode,ismodule
|
|
8
8
|
try:
|
|
9
9
|
from types import WrapperDescriptorType,MethodWrapperType,\
|
|
10
10
|
MethodDescriptorType,ClassMethodDescriptorType
|
|
@@ -13,8 +13,9 @@ except ImportError: # 低于3.7的版本
|
|
|
13
13
|
MethodDescriptorType
|
|
14
14
|
ClassMethodDescriptorType = type(dict.__dict__['fromkeys'])
|
|
15
15
|
|
|
16
|
-
try:from pyobject import objectname,shortrepr
|
|
17
|
-
except ImportError:
|
|
16
|
+
try:from pyobject import objectname,shortrepr,isfunc
|
|
17
|
+
except ImportError:
|
|
18
|
+
from __init__ import objectname,shortrepr,isfunc
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
_IMAGE_PATH=os.path.join(os.path.split(__file__)[0],"images")
|
|
@@ -24,27 +25,15 @@ TYPE_EXTRA_ATTRS = ("__basicsize__","__dictoffset__","__flags__",
|
|
|
24
25
|
"__itemsize__","__weakrefoffset__")
|
|
25
26
|
TYPE_EXTRA_CLASS_ATTRS = ("__base__","__bases__","__mro__")
|
|
26
27
|
|
|
27
|
-
def isfunc(obj):
|
|
28
|
-
# 判断一个对象是否为函数或方法
|
|
29
|
-
if isfunction(obj) or ismethod(obj):return True
|
|
30
|
-
# 使用typing而不用types.WrapperDescriptorType是为了与旧版本兼容
|
|
31
|
-
func_types=[types.LambdaType,types.BuiltinFunctionType,
|
|
32
|
-
types.BuiltinMethodType,WrapperDescriptorType,
|
|
33
|
-
MethodWrapperType,MethodDescriptorType,
|
|
34
|
-
ClassMethodDescriptorType]
|
|
35
|
-
for type_ in func_types:
|
|
36
|
-
if isinstance(obj,type_):
|
|
37
|
-
return True
|
|
38
|
-
return False
|
|
39
28
|
def isdict(obj):
|
|
40
|
-
#
|
|
29
|
+
# 判断对象是否为字典
|
|
41
30
|
dict_types=[dict,types.MappingProxyType]
|
|
42
31
|
for type in dict_types:
|
|
43
32
|
if isinstance(obj,type):return True
|
|
44
33
|
return False
|
|
45
34
|
|
|
46
35
|
def get_dpi_scale():
|
|
47
|
-
# 获取Windows的当前DPI,仅Windows
|
|
36
|
+
# 获取Windows的当前DPI,仅Windows
|
|
48
37
|
hdc = ctypes.windll.user32.GetDC(0)
|
|
49
38
|
dpi_x = ctypes.windll.gdi32.GetDeviceCaps(hdc, 88) # 88: LOGPIXELSX
|
|
50
39
|
dpi_y = ctypes.windll.gdi32.GetDeviceCaps(hdc, 90) # 90: LOGPIXELSY
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
"""
|
|
2
|
-
For the documentation, please refer to https://github.com/
|
|
1
|
+
"""Tools for manipulating Python native bytecode.
|
|
2
|
+
For the documentation, please refer to https://github.com/ekcbw/pyobject ."""
|
|
3
3
|
import sys
|
|
4
4
|
try:
|
|
5
5
|
from importlib._bootstrap_external import MAGIC_NUMBER
|
|
@@ -25,10 +25,11 @@ class Code:
|
|
|
25
25
|
>>> def f():print("Hello")
|
|
26
26
|
|
|
27
27
|
>>> c=Code.fromfunc(f)
|
|
28
|
-
>>> c.co_consts
|
|
29
|
-
|
|
30
|
-
>>> # c.co_consts=(None, 'Hello World!') #
|
|
31
|
-
>>>
|
|
28
|
+
>>> c.co_consts in [(None, 'Hello'), ('Hello', None)]
|
|
29
|
+
True
|
|
30
|
+
>>> # c.co_consts=(None, 'Hello World!') # 原先的代码
|
|
31
|
+
>>> # 兼容3.14,3.14中c.consts为('Hello', None)
|
|
32
|
+
>>> c.co_consts=tuple(('Hello World!' if item=='Hello' else item) for item in c.co_consts)
|
|
32
33
|
>>> c.exec()
|
|
33
34
|
Hello World!
|
|
34
35
|
>>>
|
|
@@ -4,7 +4,7 @@ from pyobject.objproxy.optimize import optimize_code
|
|
|
4
4
|
from pyobject.objproxy.utils import *
|
|
5
5
|
|
|
6
6
|
try:from pyobject import get_type_flag
|
|
7
|
-
except ImportError:get_type_flag=None
|
|
7
|
+
except ImportError:get_type_flag = None
|
|
8
8
|
try:from timer_tool import timer # pip install timer-tool
|
|
9
9
|
except ImportError:timer=lambda func:func
|
|
10
10
|
|
|
@@ -26,6 +26,7 @@ def unproxy_obj(obj):
|
|
|
26
26
|
class _EmptyTarget:
|
|
27
27
|
def __bool__(self):return False
|
|
28
28
|
EMPTY_OBJ = _EmptyTarget() # 空对象的特殊值
|
|
29
|
+
|
|
29
30
|
class ReprFormatProxy:
|
|
30
31
|
def __init__(self,target_obj,repr_func):
|
|
31
32
|
self.target_obj = target_obj
|