pyobject 1.3.2__tar.gz → 1.3.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.
Files changed (47) hide show
  1. {pyobject-1.3.2 → pyobject-1.3.3}/LICENSE +21 -21
  2. pyobject-1.3.3/MANIFEST.in +3 -0
  3. {pyobject-1.3.2/pyobject.egg-info → pyobject-1.3.3}/PKG-INFO +46 -31
  4. {pyobject-1.3.2 → pyobject-1.3.3}/README.rst +31 -26
  5. pyobject-1.3.3/pyobject/__init__.py +146 -0
  6. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject/browser.py +7 -18
  7. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject/code.py +6 -5
  8. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject/objproxy/__init__.py +2 -1
  9. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject/pyobj_extension.c +18 -18
  10. {pyobject-1.3.2 → pyobject-1.3.3/pyobject.egg-info}/PKG-INFO +46 -31
  11. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject.egg-info/SOURCES.txt +0 -7
  12. {pyobject-1.3.2 → pyobject-1.3.3}/setup.py +3 -3
  13. pyobject-1.3.2/MANIFEST.in +0 -5
  14. pyobject-1.3.2/pyobject/__init__.py +0 -113
  15. pyobject-1.3.2/pyobject/examples/README.md +0 -7
  16. pyobject-1.3.2/pyobject/examples/__init__.py +0 -1
  17. pyobject-1.3.2/pyobject/examples/empty_cp37.pyc +0 -0
  18. pyobject-1.3.2/pyobject/examples/pyc_zipper_unpack.py +0 -55
  19. pyobject-1.3.2/pyobject/examples/pyc_zipper_zlib.py +0 -58
  20. pyobject-1.3.2/pyobject/examples/test_inject.py +0 -134
  21. pyobject-1.3.2/pyobject/other/browser_chs_locale.py +0 -489
  22. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject/images/back.gif +0 -0
  23. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject/images/codeobject.gif +0 -0
  24. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject/images/dict.gif +0 -0
  25. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject/images/empty_dict.gif +0 -0
  26. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject/images/empty_list.gif +0 -0
  27. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject/images/empty_tuple.gif +0 -0
  28. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject/images/forward.gif +0 -0
  29. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject/images/function.gif +0 -0
  30. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject/images/list.gif +0 -0
  31. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject/images/number.gif +0 -0
  32. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject/images/python.gif +0 -0
  33. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject/images/python.ico +0 -0
  34. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject/images/refresh.gif +0 -0
  35. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject/images/string.gif +0 -0
  36. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject/images/tuple.gif +0 -0
  37. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject/objproxy/builtin_hook.py +0 -0
  38. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject/objproxy/optimize.py +0 -0
  39. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject/objproxy/utils.py +0 -0
  40. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject/search.py +0 -0
  41. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject/tests/test_code.py +0 -0
  42. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject/tests/test_objproxy.py +0 -0
  43. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject/tests/test_objproxy_perf.py +0 -0
  44. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject.egg-info/dependency_links.txt +0 -0
  45. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject.egg-info/requires.txt +0 -0
  46. {pyobject-1.3.2 → pyobject-1.3.3}/pyobject.egg-info/top_level.txt +0 -0
  47. {pyobject-1.3.2 → pyobject-1.3.3}/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
3
+ Version: 1.3.3
4
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
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,6 +14,16 @@ 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
 
@@ -52,21 +62,23 @@ file=sys.stdout)**:
52
62
  for debugging purpose. The alias is ``desc()``.
53
63
  | - maxlevel: The depth of attribute levels to print. - tab: Number of
54
64
  spaces for indentation, default is 4. - verbose: Boolean indicating
55
- whether to print special methods (e.g., ``__init__``). - file: A
65
+ whether to print special methods (e.g., ``__init__``). - maxlength:
66
+ The maximum output length of one object. - ignore_funcs: If set to
67
+ True, methods or functions of the object will not be output. - file: A
56
68
  file-like object for output.
57
69
 
58
70
  **browse(object, verbose=False, name=‘obj’)**:
59
71
 
60
- Browse any Python objects in a graphical interface using tkinter. -
61
- verbose: Same as in ``describe``, whether to print special methods.
72
+ Browse any Python objects in a GUI using tkinter. - verbose: Same as in
73
+ ``describe()``, whether to print special methods.
62
74
 
63
- The graphical interface of the browse() function is shown below:
75
+ The GUI of browse() function is:
64
76
 
65
77
  .. figure::
66
- https://i-blog.csdnimg.cn/direct/79e4deceb28e457088479db44efe35f8.png
67
- :alt: browse function GUI
78
+ https://i-blog.csdnimg.cn/direct/a4d513de3c234ef29b382c026b2bac20.png
79
+ :alt: GUI of browse()
68
80
 
69
- browse function GUI
81
+ GUI of browse()
70
82
 
71
83
  **bases(obj, level=0, tab=4)**:
72
84
 
@@ -99,8 +111,8 @@ strings.
99
111
  Class: ``pyobject.Code``
100
112
  ------------------------
101
113
 
102
- The ``Code`` class provides a wrapper for Python bytecode objects,
103
- making it easier to manipulate Python bytecode.
114
+ The ``Code`` class provides a wrapper for Python bytecode objects to
115
+ manipulate them.
104
116
 
105
117
  Python’s internal bytecode object, ``CodeType`` (e.g.,
106
118
  ``func.__code__``), is immutable. The ``Code`` class offers a
@@ -112,7 +124,7 @@ compatible**. Bytecode generated by different versions of the Python
112
124
  interpreter is incompatible.
113
125
 
114
126
  The ``Code`` class provides a **universal interface** for bytecode,
115
- supporting all Python versions from **3.4 to 3.14** (including PyPy’s
127
+ supporting all Python versions from **3.6 to 3.14** (including PyPy’s
116
128
  ``.pyc`` format), simplifying complex version compatibility issues.
117
129
 
118
130
  Constructor (``def __init__(self, code=None)``)
@@ -463,13 +475,13 @@ Increases the reference count of an object.
463
475
 
464
476
  | Get the actual reference count of the object before calling this
465
477
  function.
466
- | Unlike sys.getrefcount(), this function does not consider the
478
+ | Unlike ``sys.getrefcount()``, this function does not consider the
467
479
  additional reference count that is created when the function is
468
480
  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.
481
+ | For example, ``getrealrefcount([])`` will return 0, since after the
482
+ call finishes, ``[]`` will never be referenced by any objects, whereas
483
+ ``sys.getrefcount([])`` will return 1.
484
+ | Additionally, ``a=[]; getrealrefcount(a)`` will return 1 instead of 2.
473
485
 
474
486
  **setrefcount(obj, n)**:
475
487
 
@@ -480,9 +492,9 @@ Increases the reference count of an object.
480
492
 
481
493
  **getrefcount_nogil(obj)** and **setrefcount_nogil(obj, ref_data)**:
482
494
 
483
- In the GIL-free version of Python 3.14+, get and set reference counts,
495
+ In the GIL-free version of Python 3.13+, get and set reference counts,
484
496
  where ``ref_data`` is ``(ob_ref_local, ob_ref_shared)``, without
485
- considering the reference counts added during the call. (Experimental)
497
+ considering the reference counts added during the call.
486
498
 
487
499
  *Warning: Improper use of these functions above may lead to crashes.*
488
500
 
@@ -493,11 +505,14 @@ Python call “obj in lst” that invokes the “==” operator (``__eq__``)
493
505
  multiple times, this function directly compares the pointers to improve
494
506
  efficiency.
495
507
 
496
- **Current Version of ``pyobject``**: 1.3.2
508
+ **Current Version of ``pyobject``**: 1.3.3
497
509
 
498
510
  Change Log
499
511
  ----------
500
512
 
513
+ | 2026-1-4(v1.3.3): Improved the support for Python 3.14 and
514
+ ``describe()`` function. Adjusted the minimum supported Python version
515
+ to 3.6.
501
516
  | 2025-6-23(v1.3.2): Added the ``use_exported_obj`` parameter to the
502
517
  pyobject.objproxy module and further optimized the performance.
503
518
  | 2025-6-6(v1.3.0): Optimized the performance of the pyobject.objproxy
@@ -519,8 +534,8 @@ Change Log
519
534
  | 2024-10-24 (v1.2.5): Fixed high DPI support for ``pyobject.browser``
520
535
  on Windows, modified the ``pyobj_extension`` module, along with other
521
536
  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
537
+ | 2024-08-12 (v1.2.4): Added support for Python 3.10 and above in
538
+ ``pyobject.code_``; further optimized search performance in the
524
539
  ``search`` module, along with various other fixes and improvements.
525
540
  | 2024-06-20 (v1.2.3): Updated the ``.pyc`` file packing tool in the
526
541
  ``test`` directory of the package, and enhanced the object browser in
@@ -535,9 +550,9 @@ Change Log
535
550
  introduced editing properties functionality in ``browser``, and added
536
551
  doctests for the ``Code`` class.
537
552
 
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
553
+ .. |Stars| image:: https://img.shields.io/github/stars/ekcbw/pyobject
554
+ :target: https://img.shields.io/github/stars/ekcbw/pyobject
555
+ .. |GitHub release| image:: https://img.shields.io/github/v/release/ekcbw/pyobject
556
+ :target: https://github.com/ekcbw/pyobject/releases/latest
557
+ .. |License: MIT| image:: https://img.shields.io/github/license/ekcbw/pyobject
558
+ :target: https://github.com/ekcbw/pyobject/blob/main/LICENSE
@@ -35,21 +35,23 @@ file=sys.stdout)**:
35
35
  for debugging purpose. The alias is ``desc()``.
36
36
  | - maxlevel: The depth of attribute levels to print. - tab: Number of
37
37
  spaces for indentation, default is 4. - verbose: Boolean indicating
38
- whether to print special methods (e.g., ``__init__``). - file: A
38
+ whether to print special methods (e.g., ``__init__``). - maxlength:
39
+ The maximum output length of one object. - ignore_funcs: If set to
40
+ True, methods or functions of the object will not be output. - file: A
39
41
  file-like object for output.
40
42
 
41
43
  **browse(object, verbose=False, name=‘obj’)**:
42
44
 
43
- Browse any Python objects in a graphical interface using tkinter. -
44
- verbose: Same as in ``describe``, whether to print special methods.
45
+ Browse any Python objects in a GUI using tkinter. - verbose: Same as in
46
+ ``describe()``, whether to print special methods.
45
47
 
46
- The graphical interface of the browse() function is shown below:
48
+ The GUI of browse() function is:
47
49
 
48
50
  .. figure::
49
- https://i-blog.csdnimg.cn/direct/79e4deceb28e457088479db44efe35f8.png
50
- :alt: browse function GUI
51
+ https://i-blog.csdnimg.cn/direct/a4d513de3c234ef29b382c026b2bac20.png
52
+ :alt: GUI of browse()
51
53
 
52
- browse function GUI
54
+ GUI of browse()
53
55
 
54
56
  **bases(obj, level=0, tab=4)**:
55
57
 
@@ -82,8 +84,8 @@ strings.
82
84
  Class: ``pyobject.Code``
83
85
  ------------------------
84
86
 
85
- The ``Code`` class provides a wrapper for Python bytecode objects,
86
- making it easier to manipulate Python bytecode.
87
+ The ``Code`` class provides a wrapper for Python bytecode objects to
88
+ manipulate them.
87
89
 
88
90
  Python’s internal bytecode object, ``CodeType`` (e.g.,
89
91
  ``func.__code__``), is immutable. The ``Code`` class offers a
@@ -95,7 +97,7 @@ compatible**. Bytecode generated by different versions of the Python
95
97
  interpreter is incompatible.
96
98
 
97
99
  The ``Code`` class provides a **universal interface** for bytecode,
98
- supporting all Python versions from **3.4 to 3.14** (including PyPy’s
100
+ supporting all Python versions from **3.6 to 3.14** (including PyPy’s
99
101
  ``.pyc`` format), simplifying complex version compatibility issues.
100
102
 
101
103
  Constructor (``def __init__(self, code=None)``)
@@ -446,13 +448,13 @@ Increases the reference count of an object.
446
448
 
447
449
  | Get the actual reference count of the object before calling this
448
450
  function.
449
- | Unlike sys.getrefcount(), this function does not consider the
451
+ | Unlike ``sys.getrefcount()``, this function does not consider the
450
452
  additional reference count that is created when the function is
451
453
  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.
454
+ | For example, ``getrealrefcount([])`` will return 0, since after the
455
+ call finishes, ``[]`` will never be referenced by any objects, whereas
456
+ ``sys.getrefcount([])`` will return 1.
457
+ | Additionally, ``a=[]; getrealrefcount(a)`` will return 1 instead of 2.
456
458
 
457
459
  **setrefcount(obj, n)**:
458
460
 
@@ -463,9 +465,9 @@ Increases the reference count of an object.
463
465
 
464
466
  **getrefcount_nogil(obj)** and **setrefcount_nogil(obj, ref_data)**:
465
467
 
466
- In the GIL-free version of Python 3.14+, get and set reference counts,
468
+ In the GIL-free version of Python 3.13+, get and set reference counts,
467
469
  where ``ref_data`` is ``(ob_ref_local, ob_ref_shared)``, without
468
- considering the reference counts added during the call. (Experimental)
470
+ considering the reference counts added during the call.
469
471
 
470
472
  *Warning: Improper use of these functions above may lead to crashes.*
471
473
 
@@ -476,11 +478,14 @@ Python call “obj in lst” that invokes the “==” operator (``__eq__``)
476
478
  multiple times, this function directly compares the pointers to improve
477
479
  efficiency.
478
480
 
479
- **Current Version of ``pyobject``**: 1.3.2
481
+ **Current Version of ``pyobject``**: 1.3.3
480
482
 
481
483
  Change Log
482
484
  ----------
483
485
 
486
+ | 2026-1-4(v1.3.3): Improved the support for Python 3.14 and
487
+ ``describe()`` function. Adjusted the minimum supported Python version
488
+ to 3.6.
484
489
  | 2025-6-23(v1.3.2): Added the ``use_exported_obj`` parameter to the
485
490
  pyobject.objproxy module and further optimized the performance.
486
491
  | 2025-6-6(v1.3.0): Optimized the performance of the pyobject.objproxy
@@ -502,8 +507,8 @@ Change Log
502
507
  | 2024-10-24 (v1.2.5): Fixed high DPI support for ``pyobject.browser``
503
508
  on Windows, modified the ``pyobj_extension`` module, along with other
504
509
  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
510
+ | 2024-08-12 (v1.2.4): Added support for Python 3.10 and above in
511
+ ``pyobject.code_``; further optimized search performance in the
507
512
  ``search`` module, along with various other fixes and improvements.
508
513
  | 2024-06-20 (v1.2.3): Updated the ``.pyc`` file packing tool in the
509
514
  ``test`` directory of the package, and enhanced the object browser in
@@ -518,9 +523,9 @@ Change Log
518
523
  introduced editing properties functionality in ``browser``, and added
519
524
  doctests for the ``Code`` class.
520
525
 
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
526
+ .. |Stars| image:: https://img.shields.io/github/stars/ekcbw/pyobject
527
+ :target: https://img.shields.io/github/stars/ekcbw/pyobject
528
+ .. |GitHub release| image:: https://img.shields.io/github/v/release/ekcbw/pyobject
529
+ :target: https://github.com/ekcbw/pyobject/releases/latest
530
+ .. |License: MIT| image:: https://img.shields.io/github/license/ekcbw/pyobject
531
+ :target: https://github.com/ekcbw/pyobject/blob/main/LICENSE
@@ -0,0 +1,146 @@
1
+ """A multifunctional all-in-one utility tool for managing internal Python \
2
+ objects, compatible with nearly all Python 3 versions.
3
+ 一个多功能合一的提供操作Python对象底层工具的Python包, 支持几乎所有Python 3版本。
4
+ """
5
+ import sys, types
6
+ from warnings import warn
7
+ from pprint import pprint
8
+ from inspect import isfunction,ismethod
9
+ try:
10
+ from types import WrapperDescriptorType,MethodWrapperType,\
11
+ MethodDescriptorType,ClassMethodDescriptorType
12
+ except ImportError: # 低于3.7的版本
13
+ from typing import WrapperDescriptorType,MethodWrapperType,\
14
+ MethodDescriptorType
15
+ ClassMethodDescriptorType = type(dict.__dict__['fromkeys'])
16
+
17
+ __version__="1.3.3"
18
+
19
+ __all__=["objectname","bases","describe","desc"]
20
+ _always_ignored_names=["__builtins__","__doc__"]
21
+
22
+ MAXLENGTH=150
23
+
24
+ def isfunc(obj):
25
+ # 判断一个对象是否为函数或方法
26
+ if isfunction(obj) or ismethod(obj):return True
27
+ # 使用typing而不用types.WrapperDescriptorType是为了与旧版本兼容
28
+ func_types=[types.LambdaType,types.BuiltinFunctionType,
29
+ types.BuiltinMethodType,WrapperDescriptorType,
30
+ MethodWrapperType,MethodDescriptorType,
31
+ ClassMethodDescriptorType]
32
+ for type_ in func_types:
33
+ if isinstance(obj,type_):
34
+ return True
35
+ return False
36
+
37
+ def objectname(obj):
38
+ # 返回对象的全名,类似__qualname__属性
39
+ # if hasattr(obj,"__qualname__"):return obj.__qualname__
40
+ if not obj.__class__==type:obj=obj.__class__
41
+ if not hasattr(obj,"__module__") or obj.__module__=="__main__":
42
+ return obj.__name__
43
+ return "{}.{}".format(obj.__module__,obj.__name__)
44
+
45
+ def bases(obj,level=0,tab=4):
46
+ # 打印对象的基类
47
+ if not obj.__class__==type:obj=obj.__class__
48
+ if obj.__bases__:
49
+ if level:print(' '*(level*tab),end='')
50
+ print(*obj.__bases__,sep=',')
51
+ for cls in obj.__bases__:
52
+ bases(cls,level,tab)
53
+
54
+ _trans_table=str.maketrans("\n\t"," ") # 替换特殊字符为空格
55
+ def shortrepr(obj,maxlength=None,repr_func=None):
56
+ if repr_func is None:repr_func = repr
57
+ if maxlength is None:maxlength = MAXLENGTH
58
+ result=repr_func(obj).translate(_trans_table)
59
+ if len(result)>maxlength:
60
+ return result[:maxlength]+"..."
61
+ return result
62
+
63
+ def describe(obj,level=0,maxlevel=1,tab=4,verbose=False,file=None,
64
+ maxlength=None,ignore_funcs=False):
65
+ '''"Describe" an object by printing its attributes.
66
+ Parameters:
67
+ maxlevel: The number of levels to print the object's attributes.
68
+ tab: The number of spaces for indentation, default is 4.
69
+ verbose: Whether to output attributes starting with "_" (e.g., __init__).
70
+ maxlength: The maximum output length of one object.
71
+ ignore_funcs: If set to True, methods or functions of the object will not be output.
72
+ file: A file-like object for printing output.
73
+ '''
74
+ if file is None:file=sys.stdout
75
+ if level==maxlevel:
76
+ result=repr(obj)
77
+ if result.startswith('[') or result.startswith('{'):pprint(result)
78
+ else:print(result,file=file)
79
+ elif level>maxlevel:
80
+ raise ValueError("Argument level is larger than maxlevel")
81
+ else:
82
+ print(shortrepr(obj,maxlength)+': ',file=file)
83
+ if type(obj) is type:
84
+ print("Base classes of the object:",file=file)
85
+ bases(obj,level+1,tab)
86
+ print(file=file)
87
+ for attr in dir(obj):
88
+ if verbose or not attr.startswith("_"):
89
+ print(' '*tab*(level+1),end='',file=file)
90
+ try:
91
+ value = getattr(obj,attr)
92
+ if ignore_funcs and isfunc(value):
93
+ continue
94
+ print(f"{attr}: ",file=file)
95
+ if attr in _always_ignored_names:
96
+ describe(value,level+1,maxlevel,tab,verbose,file,maxlength)
97
+ else:
98
+ print(shortrepr(value,maxlength),file=file)
99
+ except AttributeError:
100
+ print(f"{attr}: <AttributeError!>",file=file)
101
+ if isinstance(obj, list):
102
+ print("\nList items of the object:",file=file)
103
+ for i,item in enumerate(obj):
104
+ print(f"{' '*tab*(level+1)}{i}: ",end='',file=file)
105
+ describe(item,level+1,maxlevel,tab,verbose,file,maxlength)
106
+ if isinstance(obj, dict):
107
+ print("\nDictionary items of the object:",file=file)
108
+ for key in obj.keys():
109
+ print(f"{' '*tab*(level+1)}{key!r}: ",end='',file=file)
110
+ try:
111
+ describe(obj[key],level+1,maxlevel,tab,verbose,file,maxlength)
112
+ except KeyError:
113
+ print("<KeyError!>",file=file)
114
+
115
+ desc = describe #别名
116
+
117
+ # 导入其他子模块中的函数和类
118
+ try:
119
+ from pyobject.browser import browse
120
+ __all__.append("browse")
121
+ except ImportError:warn("Failed to import module pyobject.browser.")
122
+ try:
123
+ from pyobject.search import make_list,make_iter,search
124
+ __all__.extend(["make_list","make_iter","search"])
125
+ except ImportError:warn("Failed to import pyobject.search.")
126
+
127
+ try:
128
+ from pyobject.code import Code
129
+ __all__.append("Code")
130
+ except ImportError:warn("Failed to import pyobject.code.")
131
+ try:
132
+ from pyobject.pyobj_extension import *
133
+ __all__.extend(["convptr","py_incref","py_decref","getrealrefcount",
134
+ "setrefcount","list_in","getrefcount_nogil","setrefcount_nogil",
135
+ "get_type_flag","set_type_flag","set_type_base","set_type_bases",
136
+ "set_type_mro","get_type_subclasses","set_type_subclasses",
137
+ "set_type_subclasses_by_cls"])
138
+ except ImportError:warn("Failed to import pyobject.pyobj_extension.")
139
+ try:
140
+ from pyobject.objproxy import ObjChain,ProxiedObj,unproxy_obj
141
+ __all__.extend(["ObjChain","ProxiedObj","unproxy_obj"])
142
+ except ImportError as err:
143
+ warn("Failed to import pyobject.objproxy (%s): %s"%(type(err).__name__,err))
144
+
145
+ if __name__=="__main__":
146
+ describe(type,verbose=True)
@@ -1,10 +1,10 @@
1
1
  "以图形方式浏览Python对象的模块。A module providing a visual interface to browse Python objects."
2
- import sys,os,types,typing,ctypes
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
1
  """操作Python字节码的工具。Tools for manipulating Python native bytecode.
2
- For the documentation, please refer to https://github.com/qfcy/pyobject ."""
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