[Question]
  [
Just like [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), [restricted-source](/questions/tagged/restricted-source "show questions tagged 'restricted-source'") pushes one to exploit quirks and hidden features of the Python language. We already have [a place](https://codegolf.stackexchange.com/q/54) to collect all these [tips](/questions/tagged/tips "show questions tagged 'tips'") for [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), those for [restricted-source](/questions/tagged/restricted-source "show questions tagged 'restricted-source'") remain transmitted by word of mouth or hidden deep within the python documentation.
So today I would like to ask you what are some [tips](/questions/tagged/tips "show questions tagged 'tips'") for solving [restricted-source](/questions/tagged/restricted-source "show questions tagged 'restricted-source'") challenges in Python?
Please only include 1 tip per answer.
---
## What makes a good tip here?
There are a couple of criteria I think a good tip should have:
1. It should be (somewhat) non obvious.
Similar to the [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'") tips it should be something that someone who has golfed in python a bit and read the tips page would not immediately think of. For example "Replace `a + b` with `a+b` to avoid using spaces", is obvious to any golfer, since it is already a way to make your code shorter. Thus it is not a good tip here.
2. It should not be too specific.
Since there are many different types of source restrictions, answers here should be at least somewhat applicable to multiple source restrictions, or one common source restriction. For example tips of the form **How to X without using character(s) Y** are generally useful since banned characters is a common source restriction. The thing your tip helps to do should also be somewhat general. For example tips of the form **How to create numbers with X restriction** are useful since many programs utilize numbers regardless of the challenge. Tips of the form **How to implement Shor's algorithm with X restriction** are basically just answers to a challenge you just invented and not very helpful to people solving other challenges.
  
[Answer]
# Avoid "normal" letters
Identifiers are [normalized](https://stackoverflow.com/q/62256014/2586922) by the Python 3 parser. This implies that cursive (Unicode) letters such as `ùì™ùì´ùì¨ùììùìîùìï` are interpreted as their ASCII-compliant equivalents `abcDEF`. So the following code [works](https://tio.run/##K6gsycjPM/7//8PcyXNtDY2MuYCMnUC8G4g3AfF2IN6rAZLV/P8fAA) (as was exploited [here](https://codegolf.stackexchange.com/a/207563/36398)):
```
ùìù=123
ùìπùìªùì≤ùì∑ùìΩ(ùìù)
```
Python versions in which this behaviour is confirmed:
* Works: 3.4, 3.5, 3.6, 3.7, 3.8
* Doesn't work: 2.7
### Example source restriction:
* *Use no characters `abc¬∑¬∑¬∑xyz`, `ABC¬∑¬∑¬∑XYZ`.*
[Answer]
# Avoid Numbers with Booleans
When performing arithmetic operations on Booleans, Python treats them as if they are the numbers 1 and 0. So for example
```
>>> True+False
1
```
You can make all positive numbers by just adding booleans to each other.
You can also substitute the booleans for boolean values, for example `[]>[]` is `False` and `[[]]>[]` is `True` so
```
>>> ([]>[])+([[]]>[])
1
```
In some cases, Booleans can even be used in place of a number without having to using arithmetic to cast it. For example, you can index into lists/tuples/strings with Booleans, so:
```
>>> ['a','b'][True]
'b'
```
---
### Example source restrictions:
* *Use no digits (`0123456789`)*
* *Use no alphanumeric characters*
* *Use no `if` conditions*
[Answer]
## Avoid Parens with List indexing
Parentheses are super useful for creating the correct operator precedence so it is a bummer when they are banned. However if `[]` are still available we can use them instead. Simply replace
```
(...)
```
with
```
[...][0]
```
This creates a list and indexes it to get its only element. The list causes the inside to be evaluated first solving your precedence issue.
The example above uses the characters `[]0` to do this however there are other third characters that can be used in this case if need be.
* Using characters `[]>` write `[...][[]>[]]`
* Using characters `[]<` write `[...][[]<[]]`
* Using characters `[]=` write `[...][[[]]==[]]`
---
### Example source restriction:
* *Use no parentheses*
[Answer]
## Function calls without parentheses
[We can avoid using parentheses for operator precedence using list indexing](https://codegolf.stackexchange.com/a/209737/56656), but parentheses are still very useful for calling functions.
List indexing can be used here as well to solve the issue, however it is a lot more complex so I've made it its own answer.
In order to call a function we start by making a new class which has it's indexing defined to be the function. So if we want to call `print` this might look like
```
class c:__class_getitem__=print
```
Then to call the function we simply index it with the argument we want. For example to print `"Hello World"` we do
```
c["Hello World"]
```
This has a few unfortunate short comings:
* It can only be used to call functions with one parameter.
* There are quite a few characters that are required to pull this trick off. ( `:=[]_acegilmst`)
* It uses up a lot of characters if you are doing [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'")
But sometimes it might be your only option.
---
## Example source restriction:
* Use no parentheses
[Here's](https://codegolf.stackexchange.com/a/207662/56656) an example of it being used.
[Answer]
# Use `<<` and `|` to generate constant without `+`
Fun fact: You can get any positive constant only using `[]<|`. The way to go is left-shifting a boolean. `[]<[[]]` is 1, so `[]<[[]]<<[]<[[]]` should left-shift 1 with 1, which is 2.
Does it work?
```
>>> []<[[]]<<[]<[[]]
Traceback (most recent call last):
  File "<pyshell#29>", line 1, in <module>
    []<[[]]<<[]<[[]]
TypeError: unsupported operand type(s) for <<: 'list' and 'list'
```
...No.
The precedence is wrong. Luckily, we can resolve this with "Ad Hoc Garf Hunter Parenthesis(TM)":
```
>>> [[]<[[]]][[]<[]]<<[[]<[[]]][[]<[]]
2
```
Aha!
To get numbers other than power of two, you still need `+`... or not. `|` or `[bitwise or][[]<[]]`\* will do that for you.
```
>>> [[]<[[]]][[]<[]]<<[[]<[[]]][[]<[]]<<[[]<[[]]][[]<[]]<<[[]<[[]]][[]<[]]|[[]<[[]]][[]<[]]<<[[]<[[]]][[]<[]]
10
```
To get negative numbers without `-`, you may want to use `~`.
\* That part was enclosed in an "Ad Hoc Garf Hunter Parenthesis(TM)" to indicate precedence.
[Answer]
## Access methods and built-in functions through `__dict__`
Classes contain a `__dict__` attribute, which maps their method names to the methods themselves. If you can't type a method name directly, you can get them from this `__dict__`.
For example, let's say you need to append something to a list, but you can't use the characters `p,n,+`, etc. Since `append()` is the 26th method in a list's `__dict__`, you can call the method like this:
```
a = [1,2,3]
list(a.__class__.__dict__.values())[26](a, 4)
print(a)  # prints [1,2,3,4]
```
[Try it online!](https://tio.run/##K6gsycjPM/7/P1HBViHaUMdIxziWKyezuEQjUS8@Pjknsbg4Ph7ISslMLgEyyhJzSlOLNTQ1o43MYjUSdRRMNLkKijLzgMo1//8HAA "Python 3 ‚Äì Try It Online")
This can also be used with `__builtins__` to access built-in functions. Even if someone bans the character `x` to block the `exec` function, you can still call `exec` like this:
```
list(__builtins__.__dict__.values())[20]("print('Hello, World!')")
```
[Try it online!](https://tio.run/##K6gsycjPM/7/PyezuEQjPj6pNDOnJDOvOD5eLz4@JTO5BMgoS8wpTS3W0NSMNjKI1VAqKMrMK9FQ90jNycnXUQjPL8pJUVTXVNL8/x8A "Python 3 ‚Äì Try It Online")
This works best in more recent versions of Python that guarantee dictionary order, but there are probably other ways to use this in older versions, like iterating through the `__dict__` with a regex or substring match.
[Answer]
## Use `ord()` or binary strings to avoid digits
Most integers in the ranges `[32..47]` and `[58..126]` can easily be obtained from the ASCII code of a single character with:
```
x=ord('A')
# or, if parentheses are not allowed:
y=b'A'[False]
```
[Try it online!](https://tio.run/##FcqxCoAgFAXQ3a@40GBBW1vg0NJPRIPRiwLxiQop4bdbbWc4LseT7VBrUuz3Vk6yE6IB@x7XAac92XhSoICPsByhjeGb9lGIrLbvL7M2gdbq/GVje8gEhSeVHvlHLrKrLw "Python 3 ‚Äì Try It Online")
Larger integers can also be produced using from their unicode points:
```
>>>print (ord("¬±"))
177
>>> print (ord("œÄ"))
960
```
If you can use an assignment, or you need to avoid brackets you can unpack the values, instead. Note that this will not work inline, even with the walrus operator.
```
x,*_=b'A'
y,_=b'A_'
```
[Try it online!](https://tio.run/##K6gsycjPM/7/v0JHK942Sd1RnatSB8yIV/9fUJSZV6KRpl6hYKtQXVGro1AJYlTWqmv@BwA "Python 3 ‚Äì Try It Online")
### Example source restrictions:
* *Use no digits*
* *Use no digits / no parentheses / no brackets*
[Answer]
## Alternatives to `eval` and `exec`
Do you need to treat a string as code, but you can't use `eval` or `exec`? There are at least three other ways to execute a string:
### 1) timeit.timeit
```
import timeit
_=timeit.timeit("print('Hello!')", number=1)
```
[Try it online!](https://tio.run/##K6gsycjPM/7/PzO3IL@oRKEkMzc1s4Qr3hbC0INQGkoFRZl5JRrqHqk5OfmK6ppKOgp5pblJqUW2hpr//wMA "Python 3 ‚Äì Try It Online")
`timeit` runs `number` times and returns an average of how long it took. By default it runs 1 million times, so you'll almost certainly want to set `number=1` or raise an exception to break out (e.g. `"print('hello'); 0/0"`).
Thanks to [Ethan White](https://codegolf.stackexchange.com/a/209878/94694) for showing me this approach.
### 2) os.system
```
import os
c='echo "import math;print(math.pi)" | python3'
_=os.system(c)  # Prints 3.141592653589793
```
[Try it online!](https://tio.run/##K6gsycjPM/7/PzO3IL@oRCG/mCveNr9Yr7iyuCQ1V0M9NTkjX0EJKpmbWJJhrVBQlJlXogFi6xVkaiop1CgUQAxR1/z/HwA "Python 3 ‚Äì Try It Online")
`os.system` runs an arbitrary shell command and returns its exit code. If you just need to print something, you can stick to `echo`, but you can also execute arbitrary code by calling `python3` itself.
### 3) code.InteractiveInterpreter().runcode
```
from code import InteractiveInterpreter as I
i = I()
i.runcode("print('Hello!')")
```
[Try it online!](https://tio.run/##Hcs9CoAwDEDhvaeIXWwXF2d3ewypEQOalBgFT19/lse3vHLbKtzXuqjskGVGoL2IGiQ21CkbXfizKL6F6YDkCAZIITrq9ORvCr4osYV2xG2Tpo0@1voA "Python 3 ‚Äì Try It Online")
`code` is specifically designed for read-eval-print loops, and even though it's a bit clunky, this is the most powerful of the three. `timeit` and `os.system` isolate their processes, but an `InteractiveInterpreter` can use global state instead of its own:
```
from code import InteractiveInterpreter as I
a = 64
i = I(globals())
i.runcode("import math; a=math.log2(a)")
print(a)        # a = 6.0
print(math.pi)  # math is imported globally
```
[Try it online!](https://tio.run/##LYwxCsMwDEV3n0JkspcMbelScgAfQ03dRGBbQlELPb3rhCz/Pfjw5Gcr12trb@UCM78SUBFWg1gtKc5G33SoaOoLuEF0CBPcb446ol8yPzFvPgRHo37qHvHDWSlo6wNw2jlmXi4ewxCcKFXresrxCoXW/g "Python 3 ‚Äì Try It Online")
[Answer]
## Use `--` to avoid +
E.g to do `a+b`:
```
a--b
```
**Example source restriction:**
* Avoid the `+` operator
[Answer]
## Encode restricted characters and use `exec()`
Like most interpreted languages, Python can run a string as code with `eval` and `exec`. `eval` is more limited, but `exec` can handle imports, function definitions, loops, exceptions, etc.
When combined with some of the other tips about encoding characters, this allows you to write your code normally:
```
import sys
def f(i):
 return 1 if i==1 else i*f(i-1)
i=int(sys.argv[1])
print(f(i))
    
```
Then pick an encoding and pass the encoded version to `exec`:
```
exec('\x69\x6d\x70\x6f\x72\x74\x20\x73\x79\x73\x0a\x0a\x64\x65\x66\x20\x66\x28\x69\x29\x3a\x0a\x20\x72\x65\x74\x75\x72\x6e\x20\x31\x20\x69\x66\x20\x69\x3d\x3d\x31\x20\x65\x6c\x73\x65\x20\x69\x2a\x66\x28\x69\x2d\x31\x29\x0a\x0a\x69\x3d\x69\x6e\x74\x28\x73\x79\x73\x2e\x61\x72\x67\x76\x5b\x31\x5d\x29\x0a\x70\x72\x69\x6e\x74\x28\x66\x28\x69\x29\x29\x0a')
```
[Try it online!](https://tio.run/##XU87FsMgDDtO2i0x5XcXljSQl6nt0IGengpsXlMGPWEsyfbr8z6eD1VKymm7TCEbD8SQ7QzewQTcQibUVgGeeV4ZBj2jAcOaxo5zCFCia35ibc2zWurEPbWI35@yqj8Ker/O2niH@u46WofZ3eNPu0pem5HkLvd/F@HfLLKbBSNT3zlLx1@e7fcMWeP9rJ@upRT3BQ "Python 3 ‚Äì Try It Online")
[Answer]
## Replace operators with dunder methods
Most python operators are syntactic sugar for specific method calls (often called "magic methods" or "dunder methods", with "dunder" being short for "double underscore"). For example, `+` calls `__add__()`, `==` calls `__eq__()`, and `<<` calls `__lshift__()`
If operators are restricted, you can call these methods directly:
```
a = 1
print(a.__add__(1).__eq__(2))  # True
```
[Try it online!](https://tio.run/##K6gsycjPM/7/P1HBVsGQq6AoM69EI1EvPj4xJSU@XsNQE8hMLQSyjDQ1//8HAA "Python 3 ‚Äì Try It Online")
For assignment, you can use `__setitem__` on the `locals()` or `globals()` dictionaries, whether or not the variable already exists:
```
a = 1
locals().__setitem__('a',2)
locals().__setitem__('b',2)
print(a.__add__(b).__eq__(4))  # True
```
[Try it online!](https://tio.run/##K6gsycjPM/7/P1HBVsGQKyc/OTGnWENTLz6@OLUksyQ1Nz5eQz1RXcdIE4dcEliuoCgzr0QjESiVmJICFE4CqUotBLJMNDX//wcA "Python 3 ‚Äì Try It Online")
Note that you'll have to add parentheses around numbers to avoid a syntax error. `4.__eq__(4)` won't work, but `(4).__eq__(4)` will.
[Answer]
# Use `__import__("module")` instead of `import module`
To avoid whitespace in the `import statement`, or to dynamically construct the name of the module to import as a string (e.g. `"RANDOM".lower()` if you can't use a lowercase `d`). Not likely that useful because you don't often need the standard library, and you still need to be able to use `_`, `i`, `m`, `p`, `o`, `r`, `t`, `(`, and `)`.
Edit: or as Ad Hoc Garf Hunter suggests, you can use `import<tab>module` (with a literal tab character)!
[Answer]
# File Encodings
You can set a custom encoding for your Python source file in a comment at the start. This includes various Unicode things, but also [text transforms](https://docs.python.org/3/library/codecs.html#text-encodings) such as `unicode_escape` and `punycode`, which can be used for restricted source!
Here's an example:
```
# encoding: unicode_escape
print(\x22Hello, World!\x22)
```
[Attempt This Online!](https://ato.pxeger.com/run?1=m72soLIkIz9vwYKlpSVpuhY3zZUVUvOS81My89KtFErzMoHM1PjU4uTEglSugqLMvBKNmAojI4_UnJx8HYXw_KKcFEWQgCZEO9QUmGkA)
Here's the exact specification of an encoding line, from [the Python documentation](https://docs.python.org/3/reference/lexical_analysis.html#encoding-declarations):
> 
> If a comment in the first or second line of the Python script matches the regular expression `coding[=:]\s*([-\w.]+)`, this comment is processed as an encoding declaration; the first group of this expression names the encoding of the source code file
> 
> 
> 
So, for [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), the best definition is therefore `#coding:unicode_escape`.
This works not only at the file level, but also with `exec` and `eval` *if you pass them a byte string*:
```
print(eval(rb'''# encoding: unicode_escape
\x22Hello, World!\x22'''))
```
[Attempt This Online!](https://ato.pxeger.com/run?1=m72soLIkIz9vwYKlpSVpuhY3XQuKMvNKNFLLEnM0ipLU1dWVFVLzkvNTMvPSrRRK8zKBzNT41OLkxIJUrpgKIyOP1JycfB2F8PyinBRFkABQi6YmxDComTCzAQ)
Not as useful there though because you can generally just pass a constructed string.
[Answer]
This is likely not relevant to the question but it's very silly.
This is (maybe) a more portable way of water\_ghost's convoluted method of accessing builtin methods.  
The index is 26 only on CPython 3. This very small and extremely easy to understand modification allows it to run on CPython 2.7, CPython 3, PyPy 2.7 and PyPy 3 (tested on Debian 10 amd64)
```
a = [1, 2, 3]
list(a.__class__.__dict__.values())[[14,13,26,25][sum(map(ord,{__import__("sys").version[0],__import__("platform").python_implementation()[0]}))&3]](a, 4)
print(a)
```
---
The correct indices (on my system) are
```
CPython 2.7    13
CPython 3      26
PyPy 2.7       26
PyPy 3         25
```
And by a lucky coincidence `('C'+'2')%4 == 1`, `('C'+'3')%4 == 2`, `('P'+'2') == 2` and `('P'+'3') == 3`. The value 14 is there to trick you into thinking there is a pattern.
[Answer]
## Use `*` to avoid `/`
`x**-1` is equivalent to `1/x`. So to do `y/x` you can do `x**-1*y`.
If you desperately want to get rid of the `-1`, you can check out Ad Hoc Garf Hunter's other tip.
## Example source restriction:
* Avoid using the `/` character
[Answer]
## How to create characters just with numbers, quotes and backslashes
Strings can be composed with `\ooo` where `ooo` is the octal value of the character.
Eg:
```
'\141'=='a'
```
You can also use hex, at the expense of an `x` (and `a`,`b`,`c`,`d`,`e` and/or `f` if they're used):
```
'\x61'=='a'  
```
And unicode at the expense of a `u` (two pre-Python 3) and hex characters if they're used:
```
'\u2713'=='‚úì'
```
[Answer]
# `__debug__` is True
Pretty self-expl... expl...
```
>>> __debug__
True
```
]