Repository: Gallopsled/pwntools

Issue:
List comprehension in __all__ prevents Pylance from working
Thanks for contributing to Pwntools!   Ideas from the community help make Pwntools an amazing tool for everybody.

If you've got an idea for a new feature, please provide information about:

* What the feature does
According to https://github.com/microsoft/pylance-release/issues/289, the list comprehension in `__all__` in https://github.com/Gallopsled/pwntools/blob/4e6ccb0da17fb91e43a4f9e95edf4fd83806ba23/pwn/toplevel.py#L85 prevents [Pylance](https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance) from working (when using `from pwn import *` instead of manually importing all modules).
https://github.com/compas-dev/compas/issues/621 may be a solution instead of listing all attributes manually to fix that.
* Why the feature should exist
To make Pylance happy :smile: 
* What tests should be included
Test in VS Code to ensure it works.

If you think you can write the feature yourself, please submit a Pull Request and we can review your changes!



Discussion:
You might want to try python-language-server instead (with optional further plugins to it, like rope, flake8, isort).
It is open source (MIT license), works quite well with pwntools (at least for me) and respects your rights as a user (MIT license again).

However, here is the license of pylance: https://marketplace.visualstudio.com/items/ms-python.vscode-pylance/license
But hey, use whatever you want.

Also I am afraid of building automatic tests for such a proprietary combination (please note that VSCode is also [*not* open-source](https://code.visualstudio.com/license): see vscodium for the closest open-source match), as I have absolutely no experience complying with these two licenses.
> You might want to try python-language-server instead (with optional further plugins to it, like rope, flake8, isort).

Actually I'm using it now, while it would be greater if Pylance can work 😆 
Nevertheless, if you have a ready solution, we will be more than happy to accept it.
```python
In [1]: import pwn.toplevel

In [2]: print(pwn.toplevel.__all__)
['__doc__', '__package__', '__loader__', '__spec__', '__file__', '__cached__', '__builtins__', 'collections', 'logging', 'math', 'operator', 'os', 're', 'socks', 'signal', 'string', 'struct', 'subprocess', 'sys', 'tempfile', 'threading', 'time', 'pprint', 'pwnlib', 'args', 'asm', 'atexception', 'atexit', 'commandline', 'constants', 'context', 'data', 'dynelf', 'encoders', 'elf', 'exception', 'fmtstr', 'gdb', 'libcdb', 'log', 'memleak', 'pep237', 'regsort', 'replacements', 'rop', 'runner', 'shellcraft', 'term', 'tubes', 'ui', 'useragents', 'util', 'adb', 'update', 'cpp', 'disasm', 'make_elf', 'make_elf_from_assembly', 'Thread', 'LocalContext', 'DynELF', 'absolute_import', 'encoder', 'i386', 'amd64', 'arm', 'mips', 'Encoder', 'alphanumeric', 'encode', 'line', 'null', 'printable', 'scramble', 'Core', 'Corefile', 'Coredump', 'ELF', 'load', 'PwnlibException', 'attach', 'debug', 'debug_assembly', 'debug_shellcode', 'division', 'getLogger', 'python_2_bytes_compatible', 'pack', 'variables', 'update_var', 'FileStructure', 'submit_flag', 'FmtStr', 'fmtstr_payload', 'fmtstr_split', 'MemLeak', 'RelativeMemLeak', 'OrderedDict', 'defaultdict', 'randint', 'shuffle', 'check_cycle', 'check_cycle_', 'extract_dependencies', 'resolve_order', 'depends_on_cycle', 'sleep', 'ROP', 'SigreturnFrame', 'Ret2dlresolvePayload', 'run_assembly', 'run_shellcode', 'run_assembly_exitcode', 'run_shellcode_exitcode', 'str_input', 'Timeout', 'listen', 'process', 'PTY', 'PIPE', 'STDOUT', 'remote', 'tcp', 'udp', 'connect', 'serialtube', 'server', 'ssh', 'tube', 'six', 'types', 'raw_input', 'testpwnproc', 'yesno', 'options', 'pause', 'more', 'crc', 'iters', 'net', 'proc', 'safeeval', 'BitPolynom', 'LocalNoarchContext', 'packing', 'de_bruijn', 'cyclic', 'cyclic_find', 'metasploit_pattern', 'cyclic_metasploit', 'cyclic_metasploit_find', 'cyclic_gen', 'base64', 'binascii', 'random', 'BytesIO', 'range', 'text', 'lists', 'unhex', 'enhex', 'urlencode', 'urldecode', 'bits', 'bits_str', 'unbits', 'bitswap', 'bitswap_int', 'b64e', 'b64d', 'xor', 'xor_pair', 'xor_key', 'randoms', 'rol', 'ror', 'naf', 'isprint', 'hexii', 'default_style', 'cyclic_pregen', 'de_bruijn_gen', 'sequential_lines', 'update_cyclic_pregenerated', 'hexdump_iter', 'hexdump', 'negate', 'bnot', 'unpack', 'linux_dirent', 'dirents', 'hashlib', 'shake_256file', 'shake_256sum', 'shake_256filehex', 'shake_256sumhex', 'sha3_384file', 'sha3_384sum', 'sha3_384filehex', 'sha3_384sumhex', 'md5file', 'md5sum', 'md5filehex', 'md5sumhex', 'sha224file', 'sha224sum', 'sha224filehex', 'sha224sumhex', 'sha384file', 'sha384sum', 'sha384filehex', 'sha384sumhex', 'blake2bfile', 'blake2bsum', 'blake2bfilehex', 'blake2bsumhex', 'sha3_256file', 'sha3_256sum', 'sha3_256filehex', 'sha3_256sumhex', 'shake_128file', 'shake_128sum', 'shake_128filehex', 'shake_128sumhex', 'sha1file', 'sha1sum', 'sha1filehex', 'sha1sumhex', 'sha3_512file', 'sha3_512sum', 'sha3_512filehex', 'sha3_512sumhex', 'sha256file', 'sha256sum', 'sha256filehex', 'sha256sumhex', 'sha512file', 'sha512sum', 'sha512filehex', 'sha512sumhex', 'sha3_224file', 'sha3_224sum', 'sha3_224filehex', 'sha3_224sumhex', 'blake2sfile', 'blake2ssum', 'blake2sfilehex', 'blake2ssumhex', 'partition', 'group', 'concat', 'concat_all', 'ordlist', 'unordlist', 'findall', 'errno', 'platform', 'socket', 'stat', 'fiddling', 'align', 'align_down', 'binary_ip', 'size', 'KB', 'MB', 'GB', 'KiB', 'MiB', 'GiB', 'read', 'write', 'which', 'run_in_new_terminal', 'parse_ldd_output', 'mkdir_p', 'dealarm_shell', 'register_sizes', 'unpack_many', 'ops', 'sizes', 'ends', 'signs', 'make_single', 'return_types', 'op_verbs', 'arg_doc', 'rv_doc', 'make_multi', 'p8', 'p16', 'p32', 'p64', 'u8', 'u16', 'u32', 'u64', 'make_packer', 'make_unpacker', 'flat', 'fit', 'signed', 'unsigned', 'dd', 'pidof', 'sh_string', 'sh_prepare', 'sh_command_with', 'splash', 'Buffer', 'wget', 'pickle', 'StringIO', 'error', 'warning', 'warn', 'info', 'success']
```
I don't think we need to import the names patterning `__foo__`, and the default behavior of `from import *` is to import all names not beginning with `_`.
So we can just delete the `__all__` line to solve this, with the benefit of less polluting the namespace also.
Am I right? @Arusekk 

FYI: After commenting out the line, both pwntools and Pylance seem to work fine on my machine.
Sure, that could probably help

Resolving patch:
diff --git a/pwn/toplevel.py b/pwn/toplevel.py
--- a/pwn/toplevel.py
+++ b/pwn/toplevel.py
@@ -83,4 +83,5 @@
 debug   = log.debug
 success = log.success
 
-__all__ = [x for x in tuple(globals()) if x != '__name__']
+# Equivalence with the default behavior of "from import *"
+# __all__ = [x for x in tuple(globals()) if not x.startswith('_')]


Test patch: