python-obfuscation-framework 1.10.0__tar.gz → 1.11.1__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 (194) hide show
  1. {python_obfuscation_framework-1.10.0/python_obfuscation_framework.egg-info → python_obfuscation_framework-1.11.1}/PKG-INFO +33 -4
  2. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/README.md +32 -3
  3. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/boolean.py +18 -6
  4. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/esoteric/doc.py +6 -6
  5. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/esoteric/globals.py +17 -5
  6. python_obfuscation_framework-1.11.1/pof/obfuscator/esoteric/imports.py +257 -0
  7. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/names.py +36 -3
  8. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/remove/print.py +1 -1
  9. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/strings.py +101 -60
  10. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/cipher/rc4.py +1 -1
  11. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/stegano/ipv6encoding.py +9 -5
  12. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/stegano/macencoding.py +9 -5
  13. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/stegano/uuidencoding.py +15 -5
  14. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pyproject.toml +1 -1
  15. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1/python_obfuscation_framework.egg-info}/PKG-INFO +33 -4
  16. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/python_obfuscation_framework.egg-info/SOURCES.txt +13 -1
  17. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/tests/obfuscator/conftest.py +35 -71
  18. python_obfuscation_framework-1.11.1/tests/obfuscator/fixtures/booleans.py +30 -0
  19. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/tests/obfuscator/fixtures/complex.py +20 -51
  20. python_obfuscation_framework-1.11.1/tests/obfuscator/fixtures/compression.py +15 -0
  21. python_obfuscation_framework-1.11.1/tests/obfuscator/fixtures/decorators.py +54 -0
  22. python_obfuscation_framework-1.11.1/tests/obfuscator/fixtures/deepenc.py +14 -0
  23. python_obfuscation_framework-1.11.1/tests/obfuscator/fixtures/docs.py +10 -0
  24. python_obfuscation_framework-1.11.1/tests/obfuscator/fixtures/encoding.py +42 -0
  25. python_obfuscation_framework-1.11.1/tests/obfuscator/fixtures/esoteric.py +48 -0
  26. python_obfuscation_framework-1.11.1/tests/obfuscator/fixtures/getattr.py +27 -0
  27. python_obfuscation_framework-1.11.1/tests/obfuscator/fixtures/import.py +21 -0
  28. python_obfuscation_framework-1.11.1/tests/obfuscator/fixtures/lambda.py +4 -0
  29. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/tests/obfuscator/fixtures/moderate.py +0 -27
  30. python_obfuscation_framework-1.11.1/tests/obfuscator/fixtures/numbers.py +29 -0
  31. python_obfuscation_framework-1.11.1/tests/obfuscator/fixtures/rc4.py +36 -0
  32. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/tests/obfuscator/fixtures/simple.py +6 -4
  33. python_obfuscation_framework-1.11.1/tests/obfuscator/fixtures/strings.py +55 -0
  34. python_obfuscation_framework-1.11.1/tests/obfuscator/fixtures/try.py +6 -0
  35. python_obfuscation_framework-1.10.0/pof/obfuscator/esoteric/imports.py +0 -71
  36. python_obfuscation_framework-1.10.0/tests/obfuscator/fixtures/getattr.py +0 -10
  37. python_obfuscation_framework-1.10.0/tests/obfuscator/fixtures/multiline_strings.py +0 -22
  38. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/LICENSE +0 -0
  39. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/MANIFEST.in +0 -0
  40. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/__init__.py +0 -0
  41. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/__main__.py +0 -0
  42. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/cli.py +0 -0
  43. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/cli_v2.py +0 -0
  44. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/errors.py +0 -0
  45. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/__init__.py +0 -0
  46. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/argv.py +0 -0
  47. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/base.py +0 -0
  48. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/cpu/__init__.py +0 -0
  49. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/cpu/cpu_count.py +0 -0
  50. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/fs/__init__.py +0 -0
  51. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/fs/directory_exist.py +0 -0
  52. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/fs/directory_list_exist.py +0 -0
  53. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/fs/directory_list_missing.py +0 -0
  54. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/fs/directory_missing.py +0 -0
  55. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/fs/exec_method.py +0 -0
  56. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/fs/executable_path.py +0 -0
  57. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/fs/file_exist.py +0 -0
  58. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/fs/file_list_exist.py +0 -0
  59. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/fs/file_list_missing.py +0 -0
  60. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/fs/file_missing.py +0 -0
  61. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/fs/tmp.py +0 -0
  62. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/hardware/__init__.py +0 -0
  63. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/hardware/ram_count.py +0 -0
  64. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/hooks/__init__.py +0 -0
  65. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/hooks/debugger.py +0 -0
  66. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/hooks/tracemalloc.py +0 -0
  67. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/human/__init__.py +0 -0
  68. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/human/p.py +0 -0
  69. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/human/prompt.py +0 -0
  70. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/integrity.py +0 -0
  71. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/multi.py +0 -0
  72. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/os/__init__.py +0 -0
  73. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/os/domain.py +0 -0
  74. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/os/hostname.py +0 -0
  75. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/os/uid.py +0 -0
  76. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/os/username.py +0 -0
  77. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/processes/__init__.py +0 -0
  78. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/processes/proc_count.py +0 -0
  79. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/time/__init__.py +0 -0
  80. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/time/expire.py +0 -0
  81. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/time/uptime.py +0 -0
  82. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/time/utc.py +0 -0
  83. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/evasion/utils.py +0 -0
  84. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/logger.py +0 -0
  85. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/main.py +0 -0
  86. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/__init__.py +0 -0
  87. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/builtins.py +0 -0
  88. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/cipher/__init__.py +0 -0
  89. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/cipher/deep_encryption.py +0 -0
  90. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/cipher/rc4.py +0 -0
  91. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/cipher/shift.py +0 -0
  92. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/cipher/xor.py +0 -0
  93. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/compression/__init__.py +0 -0
  94. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/compression/bz2.py +0 -0
  95. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/compression/gzip.py +0 -0
  96. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/compression/lzma.py +0 -0
  97. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/compression/zlib.py +0 -0
  98. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/constants.py +0 -0
  99. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/controlflow/__init__.py +0 -0
  100. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/controlflow/control_flow_flatten.py +0 -0
  101. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/encoding/__init__.py +0 -0
  102. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/encoding/a85.py +0 -0
  103. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/encoding/b16.py +0 -0
  104. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/encoding/b32.py +0 -0
  105. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/encoding/b32hex.py +0 -0
  106. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/encoding/b64.py +0 -0
  107. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/encoding/b85.py +0 -0
  108. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/encoding/binascii.py +0 -0
  109. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/encoding/snt.py +0 -0
  110. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/encoding/whitespace.py +0 -0
  111. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/esoteric/__init__.py +0 -0
  112. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/esoteric/call.py +0 -0
  113. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/extract_variables.py +0 -0
  114. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/junk/__init__.py +0 -0
  115. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/junk/add_comments.py +0 -0
  116. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/junk/add_newlines.py +0 -0
  117. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/junk/dead_code.py +0 -0
  118. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/numbers.py +0 -0
  119. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/other/__init__.py +0 -0
  120. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/other/tokens.py +0 -0
  121. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/remove/__init__.py +0 -0
  122. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/remove/comments.py +0 -0
  123. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/remove/exceptions.py +0 -0
  124. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/remove/indents.py +0 -0
  125. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/remove/loggings.py +0 -0
  126. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/remove/loggings_old.py +0 -0
  127. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/remove/newline.py +0 -0
  128. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/restructure.py +0 -0
  129. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/stegano/__init__.py +0 -0
  130. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/stegano/docstrings.py +0 -0
  131. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/stegano/ipv6encoding.py +0 -0
  132. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/stegano/macencoding.py +0 -0
  133. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/obfuscator/stegano/uuidencoding.py +0 -0
  134. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/stager/__init__.py +0 -0
  135. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/stager/cipher/__init__.py +0 -0
  136. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/stager/cipher/rc4.py +0 -0
  137. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/stager/download.py +0 -0
  138. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/stager/image.py +0 -0
  139. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/stager/lots/__init__.py +0 -0
  140. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/stager/lots/cl1pnet.py +0 -0
  141. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/stager/lots/pastebin.py +0 -0
  142. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/stager/lots/pasters.py +0 -0
  143. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/stager/quine.py +0 -0
  144. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/__init__.py +0 -0
  145. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/cipher/__init__.py +0 -0
  146. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/cipher/shift.py +0 -0
  147. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/compression/__init__.py +0 -0
  148. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/compression/bz2.py +0 -0
  149. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/compression/gzip.py +0 -0
  150. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/compression/lzma.py +0 -0
  151. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/compression/zlib.py +0 -0
  152. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/encoding/__init__.py +0 -0
  153. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/encoding/a85.py +0 -0
  154. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/encoding/b16.py +0 -0
  155. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/encoding/b3.py +0 -0
  156. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/encoding/b32.py +0 -0
  157. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/encoding/b32hex.py +0 -0
  158. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/encoding/b64.py +0 -0
  159. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/encoding/b85.py +0 -0
  160. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/encoding/binascii.py +0 -0
  161. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/encoding/snt.py +0 -0
  162. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/encoding/whitespace.py +0 -0
  163. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/entropy.py +0 -0
  164. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/extract_names.py +0 -0
  165. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/format.py +0 -0
  166. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/generator/__init__.py +0 -0
  167. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/generator/advanced.py +0 -0
  168. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/generator/base.py +0 -0
  169. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/generator/basic.py +0 -0
  170. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/generator/comments.py +0 -0
  171. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/generator/comments.txt +0 -0
  172. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/generator/names.txt +0 -0
  173. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/generator/unicode.py +0 -0
  174. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/se/__init__.py +0 -0
  175. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/se/homoglyphs.py +0 -0
  176. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/se/homoglyphs.txt +0 -0
  177. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/stegano/__init__.py +0 -0
  178. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/pof/utils/tokens.py +0 -0
  179. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/python_obfuscation_framework.egg-info/dependency_links.txt +0 -0
  180. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/python_obfuscation_framework.egg-info/entry_points.txt +0 -0
  181. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/python_obfuscation_framework.egg-info/requires.txt +0 -0
  182. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/python_obfuscation_framework.egg-info/top_level.txt +0 -0
  183. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/setup.cfg +0 -0
  184. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/tests/__init__.py +0 -0
  185. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/tests/obfuscator/__init__.py +0 -0
  186. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/tests/obfuscator/fixtures/__init__.py +0 -0
  187. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/tests/obfuscator/test_edge_cases.py +0 -0
  188. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/tests/obfuscator/test_integration.py +0 -0
  189. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/tests/obfuscator/utils.py +0 -0
  190. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/tests/pyproject.toml +0 -0
  191. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/tests/utils/__init__.py +0 -0
  192. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/tests/utils/se/__init__.py +0 -0
  193. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/tests/utils/se/test_homoglyphs.py +0 -0
  194. {python_obfuscation_framework-1.10.0 → python_obfuscation_framework-1.11.1}/tests/utils/test_generator.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-obfuscation-framework
3
- Version: 1.10.0
3
+ Version: 1.11.1
4
4
  Summary: Python Obfuscation Framework
5
5
  Author-email: deoktr <35725720+deoktr@users.noreply.github.com>
6
6
  Maintainer-email: deoktr <35725720+deoktr@users.noreply.github.com>
@@ -795,20 +795,50 @@ exec(binascii.a2b_hex("".join(['7072696e-7428-2748-656c-6c6f2c20776f','726c6427-
795
795
 
796
796
  #### ImportsObfuscator
797
797
 
798
- Source: `import pathlib`
798
+ Remove keyword `import`.
799
799
 
800
800
  ```python
801
- pathlib=__import__('pathlib')
801
+ # import X
802
+ X = __import__("X")
803
+
804
+ # import X as Y
805
+ Y = __import__("X")
806
+
807
+ # import X, Y
808
+ X = __import__("X")
809
+ Y = __import__("Y")
810
+
811
+ # import X.Y
812
+ X = __import__("X.Y")
813
+
814
+ # from X import Y
815
+ Y = __import__("X", fromlist=["Y"]).Y
816
+
817
+ # from X import Y as Z
818
+ Z = __import__("X", fromlist=["Y"]).Y
819
+
820
+ # from X import Y, Z
821
+ Y = __import__("X", fromlist=["Y"]).Y
822
+ Z = __import__("X", fromlist=["Z"]).Z
802
823
  ```
803
824
 
825
+ > [!NOTE]
826
+ > Does not support wildcard imports `*`, or local imports `from . import`.
827
+
804
828
  #### CharFromDocObfuscator
805
829
 
830
+ Get a single character from a documentation.
831
+
806
832
  Source: `print('h')`
807
833
 
808
834
  ```python
809
835
  print(oct.__doc__[8])
810
836
  ```
811
837
 
838
+ > [!WARNING]
839
+ > This is highly prone to error, if the documentation change between Python
840
+ > versions, then this may break.
841
+
812
842
  #### AddCommentsObfuscator
813
843
 
814
844
  ```python
@@ -1372,7 +1402,6 @@ Other Python obfuscation projects:
1372
1402
 
1373
1403
  ## TODO
1374
1404
 
1375
- - Fix `NamesObfuscator`.
1376
1405
  - Add option to prepend a shebang, and add ability to customize it.
1377
1406
 
1378
1407
  ## License
@@ -750,20 +750,50 @@ exec(binascii.a2b_hex("".join(['7072696e-7428-2748-656c-6c6f2c20776f','726c6427-
750
750
 
751
751
  #### ImportsObfuscator
752
752
 
753
- Source: `import pathlib`
753
+ Remove keyword `import`.
754
754
 
755
755
  ```python
756
- pathlib=__import__('pathlib')
756
+ # import X
757
+ X = __import__("X")
758
+
759
+ # import X as Y
760
+ Y = __import__("X")
761
+
762
+ # import X, Y
763
+ X = __import__("X")
764
+ Y = __import__("Y")
765
+
766
+ # import X.Y
767
+ X = __import__("X.Y")
768
+
769
+ # from X import Y
770
+ Y = __import__("X", fromlist=["Y"]).Y
771
+
772
+ # from X import Y as Z
773
+ Z = __import__("X", fromlist=["Y"]).Y
774
+
775
+ # from X import Y, Z
776
+ Y = __import__("X", fromlist=["Y"]).Y
777
+ Z = __import__("X", fromlist=["Z"]).Z
757
778
  ```
758
779
 
780
+ > [!NOTE]
781
+ > Does not support wildcard imports `*`, or local imports `from . import`.
782
+
759
783
  #### CharFromDocObfuscator
760
784
 
785
+ Get a single character from a documentation.
786
+
761
787
  Source: `print('h')`
762
788
 
763
789
  ```python
764
790
  print(oct.__doc__[8])
765
791
  ```
766
792
 
793
+ > [!WARNING]
794
+ > This is highly prone to error, if the documentation change between Python
795
+ > versions, then this may break.
796
+
767
797
  #### AddCommentsObfuscator
768
798
 
769
799
  ```python
@@ -1327,7 +1357,6 @@ Other Python obfuscation projects:
1327
1357
 
1328
1358
  ## TODO
1329
1359
 
1330
- - Fix `NamesObfuscator`.
1331
1360
  - Add option to prepend a shebang, and add ability to customize it.
1332
1361
 
1333
1362
  ## License
@@ -44,24 +44,30 @@ class BooleanObfuscator:
44
44
  (RPAR, ")"),
45
45
  ]
46
46
  case 3:
47
- # not False
47
+ # (not False)
48
48
  return [
49
+ (LPAR, "("),
49
50
  (NAME, "not"),
50
51
  (NAME, "False"),
52
+ (RPAR, ")"),
51
53
  ]
52
54
  case 4:
53
- # not not True
55
+ # (not not True)
54
56
  return [
57
+ (LPAR, "("),
55
58
  (NAME, "not"),
56
59
  (NAME, "not"),
57
60
  (NAME, "True"),
61
+ (RPAR, ")"),
58
62
  ]
59
63
  case 5:
60
- # "" in ""
64
+ # ("" in "")
61
65
  return [
66
+ (LPAR, "("),
62
67
  (STRING, "''"),
63
68
  (NAME, "in"),
64
69
  (STRING, "''"),
70
+ (RPAR, ")"),
65
71
  ]
66
72
  case 6:
67
73
  # bool(1)
@@ -97,25 +103,31 @@ class BooleanObfuscator:
97
103
  (RPAR, ")"),
98
104
  ]
99
105
  case 3:
100
- # not True
106
+ # (not True)
101
107
  return [
108
+ (LPAR, "("),
102
109
  (NAME, "not"),
103
110
  (NAME, "True"),
111
+ (RPAR, ")"),
104
112
  ]
105
113
  case 4:
106
- # not not False
114
+ # (not not False)
107
115
  return [
116
+ (LPAR, "("),
108
117
  (NAME, "not"),
109
118
  (NAME, "not"),
110
119
  (NAME, "False"),
120
+ (RPAR, ")"),
111
121
  ]
112
122
  case 5:
113
- # "" not in ""
123
+ # ("" not in "")
114
124
  return [
125
+ (LPAR, "("),
115
126
  (STRING, "''"),
116
127
  (NAME, "not"),
117
128
  (NAME, "in"),
118
129
  (STRING, "''"),
130
+ (RPAR, ")"),
119
131
  ]
120
132
  case 6:
121
133
  # bool(0)
@@ -183,31 +183,31 @@ class CharFromDocObfuscator:
183
183
  )
184
184
 
185
185
  @staticmethod
186
- def get_char_indexes(string, char):
186
+ def _get_char_indexes(string, char):
187
187
  return [pos for pos, c in enumerate(string) if c == char]
188
188
 
189
189
  @classmethod
190
- def try_find_doc_index(cls, char):
190
+ def _try_find_doc_index(cls, char):
191
191
  # take a random builtin doc and search for index in it
192
192
  builtin = random.choice(cls.BUILTINS)
193
193
  doc = __builtins__[builtin].__doc__
194
194
  if not doc:
195
195
  msg = f"doc for {builtin} is not a string"
196
196
  raise PofError(msg)
197
- indexes = cls.get_char_indexes(doc, char)
197
+ indexes = cls._get_char_indexes(doc, char)
198
198
  if len(indexes) == 0:
199
199
  msg = "char not present"
200
200
  raise PofError(msg)
201
201
  index = random.choice(indexes)
202
202
  return builtin, index
203
203
 
204
- def obfuscate_char(self, char):
204
+ def _obfuscate_char(self, char):
205
205
  builtin = None
206
206
  index = None
207
207
  retry = 3
208
208
  for _ in range(retry):
209
209
  try:
210
- builtin, index = self.try_find_doc_index(char)
210
+ builtin, index = self._try_find_doc_index(char)
211
211
  except PofError:
212
212
  pass
213
213
  else:
@@ -239,7 +239,7 @@ class CharFromDocObfuscator:
239
239
  string = ast.literal_eval(tokval)
240
240
  if len(string) == 1:
241
241
  try:
242
- new_tokens = self.obfuscate_char(string)
242
+ new_tokens = self._obfuscate_char(string)
243
243
  except PofError as e:
244
244
  logger.debug(str(e))
245
245
  except Exception: # noqa: BLE001
@@ -15,7 +15,7 @@
15
15
  # along with this program. If not, see <https://www.gnu.org/licenses/>.
16
16
 
17
17
  import keyword
18
- from tokenize import LPAR, NAME, OP, RPAR, STRING
18
+ from tokenize import LPAR, NAME, NEWLINE, NL, OP, RPAR, STRING
19
19
 
20
20
 
21
21
  # TODO (deoktr): add frequency
@@ -42,14 +42,24 @@ class GlobalsObfuscator:
42
42
  def obfuscate_tokens(cls, tokens):
43
43
  local_functions = []
44
44
  prev_tokval = None
45
- for toknum, tokval, *_ in tokens:
46
- if prev_tokval in ["def", "class"] and toknum == NAME:
45
+ prev_col = -1
46
+ for toknum, tokval, *rest in tokens:
47
+ start = rest[0] if rest else (0, 0)
48
+ if prev_tokval in ["def", "class"] and toknum == NAME and prev_col == 0:
47
49
  local_functions.append(tokval)
50
+ if toknum == NAME and tokval in ("def", "class"):
51
+ prev_col = start[1]
48
52
  prev_tokval = tokval
49
53
 
50
- result = [] # obfuscated tokens
54
+ result = []
51
55
  prev_tokval = None
56
+ in_import = False
52
57
  for index, (toknum, tokval, *_) in enumerate(tokens):
58
+ if tokval in ("import", "from") and toknum == NAME:
59
+ in_import = True
60
+ elif toknum in (NEWLINE, NL):
61
+ in_import = False
62
+
53
63
  new_tokens = [(toknum, tokval)]
54
64
  next_tokval = None
55
65
  if len(tokens) > index + 1:
@@ -60,8 +70,10 @@ class GlobalsObfuscator:
60
70
  # ensure it's not a definition
61
71
  and prev_tokval not in ["def", "class", "."]
62
72
  # ensure it's not an argument of a call
63
- and next_tokval not in ["="]
73
+ and next_tokval != "="
64
74
  and tokval not in cls.RESERVED
75
+ # ensure it's not inside an import statement
76
+ and not in_import
65
77
  ):
66
78
  new_tokens = [
67
79
  (NAME, "globals"),
@@ -0,0 +1,257 @@
1
+ # POF, a free and open source Python obfuscation framework.
2
+ # Copyright (C) 2022 - 2026 Deoktr
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
16
+
17
+ from tokenize import ENDMARKER, NAME, NEWLINE, NL, OP, STRING
18
+
19
+
20
+ class ImportsObfuscator:
21
+ """Obfuscate import statements using __import__().
22
+
23
+ Supported forms:
24
+
25
+ ```
26
+ # import X
27
+ X = __import__("X")
28
+
29
+ # import X as Y
30
+ Y = __import__("X")
31
+
32
+ # import X, Y
33
+ X = __import__("X")
34
+ Y = __import__("Y")
35
+
36
+ # import X.Y
37
+ X = __import__("X.Y")
38
+
39
+ # from X import Y
40
+ Y = __import__("X", fromlist=["Y"]).Y
41
+
42
+ # from X import Y as Z
43
+ Z = __import__("X", fromlist=["Y"]).Y
44
+
45
+ # from X import Y, Z
46
+ Y = __import__("X", fromlist=["Y"]).Y
47
+ Z = __import__("X", fromlist=["Z"]).Z
48
+ ```
49
+
50
+ Left unchanged:
51
+
52
+ ```
53
+ from X import *
54
+ from . import X
55
+ ```
56
+ """
57
+
58
+ @staticmethod
59
+ def _is_statement_start(preceding_tokens: list) -> bool:
60
+ """Check if the current position is a valid statement start."""
61
+ if not preceding_tokens:
62
+ return True
63
+ for toknum, _ in reversed(preceding_tokens):
64
+ if toknum in (NEWLINE, NL, ENDMARKER):
65
+ return True
66
+ if toknum in (NAME, OP, STRING):
67
+ return False
68
+ return True
69
+
70
+ @classmethod
71
+ def _transform_import(cls, stmt_tokens: list) -> list | None:
72
+ """Transform collected import statement tokens into __import__() calls.
73
+
74
+ Returns None if the import should be left unchanged.
75
+ """
76
+ body = [
77
+ (t, v)
78
+ for t, v in stmt_tokens
79
+ if t not in (NEWLINE, NL, ENDMARKER) and v not in ("(", ")")
80
+ ]
81
+ trailing = [(t, v) for t, v in stmt_tokens if t in (NEWLINE, NL, ENDMARKER)]
82
+
83
+ if not body:
84
+ return None
85
+
86
+ first_val = body[0][1]
87
+
88
+ if first_val == "import":
89
+ return cls._transform_simple_import(body[1:]) + trailing
90
+ if first_val == "from":
91
+ t = cls._transform_from_import(body[1:])
92
+ if t is None:
93
+ return None
94
+ return t + trailing
95
+ return None
96
+
97
+ @classmethod
98
+ def _transform_simple_import(cls, tokens: list) -> list:
99
+ """Transform: import X / import X as Y / import X, Y / import X.Y."""
100
+ groups = cls._split_by_comma(tokens)
101
+ result: list = []
102
+
103
+ for group in groups:
104
+ if not group:
105
+ continue
106
+ if result:
107
+ result.append((NEWLINE, "\n"))
108
+
109
+ names, alias = cls._extract_alias(group)
110
+ module_name = cls._join_dotted_name(names)
111
+ bind_name = alias or names[0][1]
112
+
113
+ result.extend(
114
+ [
115
+ (NAME, bind_name),
116
+ (OP, "="),
117
+ (NAME, "__import__"),
118
+ (OP, "("),
119
+ (STRING, repr(module_name)),
120
+ (OP, ")"),
121
+ ],
122
+ )
123
+
124
+ return result
125
+
126
+ @classmethod
127
+ def _transform_from_import(cls, tokens: list) -> list | None:
128
+ """Transform: from X import Y / from X import Y as Z / from X import Y, Z.
129
+
130
+ Returns None for relative imports or wildcard imports.
131
+ """
132
+ import_idx = None
133
+ for idx, (_, v) in enumerate(tokens):
134
+ if v == "import":
135
+ import_idx = idx
136
+ break
137
+
138
+ if import_idx is None:
139
+ return None
140
+
141
+ module_tokens = tokens[:import_idx]
142
+ name_tokens = tokens[import_idx + 1 :]
143
+
144
+ if any(v == "." for _, v in module_tokens):
145
+ return None
146
+
147
+ if any(v == "*" for _, v in name_tokens):
148
+ return None
149
+
150
+ module_name = cls._join_dotted_name(module_tokens)
151
+
152
+ groups = cls._split_by_comma(name_tokens)
153
+ result: list = []
154
+
155
+ for group in groups:
156
+ if not group:
157
+ continue
158
+ if result:
159
+ result.append((NEWLINE, "\n"))
160
+
161
+ names, alias = cls._extract_alias(group)
162
+ imported_name = names[0][1]
163
+ bind_name = alias or imported_name
164
+
165
+ result.extend(
166
+ [
167
+ (NAME, bind_name),
168
+ (OP, "="),
169
+ (NAME, "__import__"),
170
+ (OP, "("),
171
+ (STRING, repr(module_name)),
172
+ (OP, ","),
173
+ (NAME, "fromlist"),
174
+ (OP, "="),
175
+ (OP, "["),
176
+ (STRING, repr(imported_name)),
177
+ (OP, "]"),
178
+ (OP, ")"),
179
+ (OP, "."),
180
+ (NAME, imported_name),
181
+ ],
182
+ )
183
+
184
+ return result
185
+
186
+ @staticmethod
187
+ def _split_by_comma(tokens: list) -> list[list]:
188
+ """Split a token list by comma operators."""
189
+ groups: list[list] = [[]]
190
+ for toknum, tokval in tokens:
191
+ if toknum == OP and tokval == ",":
192
+ groups.append([])
193
+ else:
194
+ groups[-1].append((toknum, tokval))
195
+ return groups
196
+
197
+ @staticmethod
198
+ def _extract_alias(tokens: list) -> tuple[list, str | None]:
199
+ """Extract name tokens and alias from a token group.
200
+
201
+ Returns (name_tokens, alias_string_or_None).
202
+ """
203
+ alias = None
204
+ name_tokens = []
205
+ saw_as = False
206
+ for toknum, tokval in tokens:
207
+ if tokval == "as":
208
+ saw_as = True
209
+ elif saw_as:
210
+ alias = tokval
211
+ saw_as = False
212
+ else:
213
+ name_tokens.append((toknum, tokval))
214
+ return name_tokens, alias
215
+
216
+ @staticmethod
217
+ def _join_dotted_name(tokens: list) -> str:
218
+ """Join NAME and OP('.') tokens into a dotted module name string."""
219
+ return "".join(v for _, v in tokens)
220
+
221
+ @classmethod
222
+ def obfuscate_tokens(cls, tokens: list) -> list:
223
+ result: list = []
224
+ i = 0
225
+ while i < len(tokens):
226
+ toknum, tokval, *_ = tokens[i]
227
+
228
+ if (
229
+ toknum == NAME
230
+ and tokval in ("import", "from")
231
+ and cls._is_statement_start(result)
232
+ ):
233
+ stmt_tokens = []
234
+ j = i
235
+ paren_depth = 0
236
+ while j < len(tokens):
237
+ st, sv, *_ = tokens[j]
238
+ stmt_tokens.append((st, sv))
239
+ if sv == "(":
240
+ paren_depth += 1
241
+ elif sv == ")":
242
+ paren_depth -= 1
243
+ if st in (NEWLINE, NL, ENDMARKER) and paren_depth <= 0:
244
+ break
245
+ j += 1
246
+
247
+ replacement = cls._transform_import(stmt_tokens)
248
+ if replacement is not None:
249
+ result.extend(replacement)
250
+ else:
251
+ result.extend(stmt_tokens)
252
+ i = j + 1
253
+ continue
254
+
255
+ result.append((toknum, tokval))
256
+ i += 1
257
+ return result
@@ -50,6 +50,22 @@ class _ScopeAnalyzer(ast.NodeVisitor):
50
50
  self.imported_names.add(alias.asname or alias.name)
51
51
  self.generic_visit(node)
52
52
 
53
+ def visit_Assign(self, node: ast.Assign) -> None:
54
+ """Detect `x = __import__(...)` and treat x as an imported name."""
55
+ if len(node.targets) == 1 and isinstance(node.targets[0], ast.Name):
56
+ value = node.value
57
+ # unwrap attribute chains: x = __import__("m", fromlist=["y"]).y
58
+ # as they could be generated from the ImportObfuscator
59
+ while isinstance(value, ast.Attribute):
60
+ value = value.value
61
+ if (
62
+ isinstance(value, ast.Call)
63
+ and isinstance(value.func, ast.Name)
64
+ and value.func.id == "__import__"
65
+ ):
66
+ self.imported_names.add(node.targets[0].id)
67
+ self.generic_visit(node)
68
+
53
69
  def visit_ClassDef(self, node: ast.ClassDef) -> None:
54
70
  self.class_names.add(node.name)
55
71
  prev = self._in_class
@@ -176,14 +192,30 @@ class _StringFixer(ast.NodeTransformer):
176
192
  node.args[1] = ast.Constant(value=self.mapping[node.args[1].value])
177
193
  return node
178
194
 
195
+ def _is_globals_call(self, node: ast.expr) -> bool:
196
+ """Check if node is a call to globals()."""
197
+ return (
198
+ isinstance(node, ast.Call)
199
+ and isinstance(node.func, ast.Name)
200
+ and node.func.id == "globals"
201
+ and not node.args
202
+ )
203
+
179
204
  def visit_Subscript(self, node: ast.Subscript) -> ast.Subscript:
180
205
  self.generic_visit(node)
181
206
  if (
182
- isinstance(node.value, ast.Attribute)
183
- and node.value.attr == "__dict__"
184
- and isinstance(node.slice, ast.Constant)
207
+ isinstance(node.slice, ast.Constant)
185
208
  and isinstance(node.slice.value, str)
186
209
  and node.slice.value in self.mapping
210
+ and (
211
+ # __dict__['name'] pattern
212
+ (
213
+ isinstance(node.value, ast.Attribute)
214
+ and node.value.attr == "__dict__"
215
+ )
216
+ # globals()['name'] pattern
217
+ or self._is_globals_call(node.value)
218
+ )
187
219
  ):
188
220
  node.slice = ast.Constant(value=self.mapping[node.slice.value])
189
221
  return node
@@ -196,6 +228,7 @@ class NamesObfuscator:
196
228
  "__file__",
197
229
  "__name__",
198
230
  "__doc__",
231
+ "__builtins__",
199
232
  "__package__",
200
233
  "__loader__",
201
234
  "__spec__",
@@ -53,7 +53,7 @@ class PrintObfuscator:
53
53
 
54
54
  if inside_print:
55
55
  if print_par_depth == parenthesis_depth and (
56
- tokval not in ("(", "print") and prev_tokval != "print"
56
+ tokval not in ("(", "print") and prev_tokval not in {"print", "."}
57
57
  ): # check if still inside print
58
58
  inside_print = False
59
59
  else: