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.
Files changed (47) hide show
  1. {pyobject-1.3.2 → pyobject-1.3.4}/LICENSE +21 -21
  2. pyobject-1.3.4/MANIFEST.in +3 -0
  3. {pyobject-1.3.2/pyobject.egg-info → pyobject-1.3.4}/PKG-INFO +60 -37
  4. {pyobject-1.3.2 → pyobject-1.3.4}/README.rst +44 -31
  5. pyobject-1.3.4/pyobject/__init__.py +145 -0
  6. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/browser.py +8 -19
  7. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/code.py +7 -6
  8. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/objproxy/__init__.py +2 -1
  9. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/pyobj_extension.c +48 -42
  10. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/search.py +1 -1
  11. {pyobject-1.3.2 → pyobject-1.3.4/pyobject.egg-info}/PKG-INFO +60 -37
  12. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject.egg-info/SOURCES.txt +0 -7
  13. {pyobject-1.3.2 → pyobject-1.3.4}/setup.py +3 -3
  14. pyobject-1.3.2/MANIFEST.in +0 -5
  15. pyobject-1.3.2/pyobject/__init__.py +0 -113
  16. pyobject-1.3.2/pyobject/examples/README.md +0 -7
  17. pyobject-1.3.2/pyobject/examples/__init__.py +0 -1
  18. pyobject-1.3.2/pyobject/examples/empty_cp37.pyc +0 -0
  19. pyobject-1.3.2/pyobject/examples/pyc_zipper_unpack.py +0 -55
  20. pyobject-1.3.2/pyobject/examples/pyc_zipper_zlib.py +0 -58
  21. pyobject-1.3.2/pyobject/examples/test_inject.py +0 -134
  22. pyobject-1.3.2/pyobject/other/browser_chs_locale.py +0 -489
  23. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/back.gif +0 -0
  24. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/codeobject.gif +0 -0
  25. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/dict.gif +0 -0
  26. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/empty_dict.gif +0 -0
  27. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/empty_list.gif +0 -0
  28. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/empty_tuple.gif +0 -0
  29. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/forward.gif +0 -0
  30. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/function.gif +0 -0
  31. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/list.gif +0 -0
  32. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/number.gif +0 -0
  33. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/python.gif +0 -0
  34. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/python.ico +0 -0
  35. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/refresh.gif +0 -0
  36. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/string.gif +0 -0
  37. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/images/tuple.gif +0 -0
  38. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/objproxy/builtin_hook.py +0 -0
  39. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/objproxy/optimize.py +0 -0
  40. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/objproxy/utils.py +0 -0
  41. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/tests/test_code.py +0 -0
  42. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/tests/test_objproxy.py +0 -0
  43. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject/tests/test_objproxy_perf.py +0 -0
  44. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject.egg-info/dependency_links.txt +0 -0
  45. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject.egg-info/requires.txt +0 -0
  46. {pyobject-1.3.2 → pyobject-1.3.4}/pyobject.egg-info/top_level.txt +0 -0
  47. {pyobject-1.3.2 → pyobject-1.3.4}/setup.cfg +0 -0
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 qfcy
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.
@@ -0,0 +1,3 @@
1
+ include pyobject/images/*
2
+ include pyobject/objproxy/*
3
+ include pyobject/tests/*
@@ -1,10 +1,10 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: pyobject
3
- Version: 1.3.2
4
- Summary: A multifunctional all-in-one utility tool for managing internal Python objects, compatible with nearly all Python 3 versions. 一个多功能合一的提供操作Python对象底层工具的Python包, 支持几乎所有Python 3版本。
5
- Home-page: https://github.com/qfcy/pyobject
6
- Author: qfcy
7
- Author-email: 3076711200@qq.com
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__``). - file: A
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 graphical interface using tkinter. -
61
- verbose: Same as in ``describe``, whether to print special methods.
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 graphical interface of the browse() function is shown below:
76
+ The GUI of browse() function is:
64
77
 
65
78
  .. figure::
66
- https://i-blog.csdnimg.cn/direct/79e4deceb28e457088479db44efe35f8.png
67
- :alt: browse function GUI
79
+ https://i-blog.csdnimg.cn/direct/a4d513de3c234ef29b382c026b2bac20.png
80
+ :alt: GUI of browse()
68
81
 
69
- browse function GUI
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
- making it easier to manipulate Python bytecode.
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.4 to 3.14** (including PyPy’s
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(), this function does not consider the
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, because after exiting
470
- getrealrefcount, the list [] is no longer referenced by any object,
471
- whereas sys.getrefcount([]) will return 1.
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.14+, get and set reference counts,
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. (Experimental)
498
+ considering the reference counts added during the call.
486
499
 
487
- *Warning: Improper use of these functions above may lead to crashes.*
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 obj in lst that invokes the “==” operator (``__eq__``)
493
- multiple times, this function directly compares the pointers to improve
494
- efficiency.
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
- **Current Version of ``pyobject``**: 1.3.2
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 versions 3.10 and above
523
- in ``pyobject.code_``; further optimized search performance in the
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/qfcy/pyobject
539
- :target: https://img.shields.io/github/stars/qfcy/pyobject
540
- .. |GitHub release| image:: https://img.shields.io/github/v/release/qfcy/pyobject
541
- :target: https://github.com/qfcy/pyobject/releases/latest
542
- .. |License: MIT| image:: https://img.shields.io/github/license/qfcy/pyobject
543
- :target: https://github.com/qfcy/pyobject/blob/main/LICENSE
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__``). - file: A
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 graphical interface using tkinter. -
44
- verbose: Same as in ``describe``, whether to print special methods.
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 graphical interface of the browse() function is shown below:
49
+ The GUI of browse() function is:
47
50
 
48
51
  .. figure::
49
- https://i-blog.csdnimg.cn/direct/79e4deceb28e457088479db44efe35f8.png
50
- :alt: browse function GUI
52
+ https://i-blog.csdnimg.cn/direct/a4d513de3c234ef29b382c026b2bac20.png
53
+ :alt: GUI of browse()
51
54
 
52
- browse function GUI
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
- making it easier to manipulate Python bytecode.
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.4 to 3.14** (including PyPy’s
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(), this function does not consider the
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, because after exiting
453
- getrealrefcount, the list [] is no longer referenced by any object,
454
- whereas sys.getrefcount([]) will return 1.
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.14+, get and set reference counts,
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. (Experimental)
471
+ considering the reference counts added during the call.
469
472
 
470
- *Warning: Improper use of these functions above may lead to crashes.*
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 obj in lst that invokes the “==” operator (``__eq__``)
476
- multiple times, this function directly compares the pointers to improve
477
- efficiency.
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
- **Current Version of ``pyobject``**: 1.3.2
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 versions 3.10 and above
506
- in ``pyobject.code_``; further optimized search performance in the
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/qfcy/pyobject
522
- :target: https://img.shields.io/github/stars/qfcy/pyobject
523
- .. |GitHub release| image:: https://img.shields.io/github/v/release/qfcy/pyobject
524
- :target: https://github.com/qfcy/pyobject/releases/latest
525
- .. |License: MIT| image:: https://img.shields.io/github/license/qfcy/pyobject
526
- :target: https://github.com/qfcy/pyobject/blob/main/LICENSE
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
- "以图形方式浏览Python对象的模块。A module providing a visual interface to browse Python objects."
2
- import sys,os,types,typing,ctypes
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 isfunction,ismethod,isgeneratorfunction,isgenerator,iscode,ismodule
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:from __init__ import objectname,shortrepr
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
- """操作Python字节码的工具。Tools for manipulating Python native bytecode.
2
- For the documentation, please refer to https://github.com/qfcy/pyobject ."""
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
- (None, 'Hello')
30
- >>> # c.co_consts=(None, 'Hello World!') # 原来的代码
31
- >>> c.co_consts=tuple(('Hello World!' if item=='Hello' else item) for item in c.co_consts) # 兼容3.14,3.14中c.consts为('Hello', None)
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