diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml new file mode 100644 index 0000000..e424e07 --- /dev/null +++ b/.github/workflows/node.js.yml @@ -0,0 +1,31 @@ +# This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions + +name: Node.js CI + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + build: + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [16.x] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + - run: npm ci + - run: npm run build --if-present + - run: npm test diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..35061b5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/typeshed.json +/node_modules/ +*.rst diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..9640701 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "python.formatting.provider": "black", + "python.analysis.typeshedPaths": [ + "/Users/mth/Development/microbit-foundation/micropython-microbit-stubs/typeshed/" + ], + "python.analysis.typeCheckingMode": "basic" +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..56c047a --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# micro:bit MicroPython stubs for editor support + +## Credit and licensing + +builtins and utility definitions are derived from [typeshed](https://github.com/python/typeshed). Further work is required to review these to ensure that we don't have stubs for definitions MicroPython does not support. These stubs don't provide documentation. + +MicroPython and micro:bit stubs are based on the restructured text documentation for [micro:bit](https://github.com/bbcmicrobit/micropython/tree/v2-docs) and, where not otherwise covered in micro:bit-specific docs, [MicroPython](https://github.com/micropython/micropython/tree/master/docs/library). These stubs provide documentation. + +Typeshed is Apache 2.0 licensed. + +MicroPython is MIT Licensed and Copyright (c) 2013-2021 Damien P. George. +MicroPython for the micro:bit is MIT licensed and Copyright (c) 2013-2016 The MicroPython-on-micro:bit Developers (see https://github.com/bbcmicrobit/micropython/blob/v2-docs/AUTHORS). + diff --git a/browser-package.py b/browser-package.py new file mode 100755 index 0000000..c558133 --- /dev/null +++ b/browser-package.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 +""" +Outputs a JSON file containing all the stubs and a Pyright config file. + +This is intended for web apps that need the stubs client side. +""" +import os +import json + +results = dict(files={}) +for (source, prefix) in (("typeshed", "/typeshed/"), ("config", "/src/")): + for (dirpath, dirnames, filenames) in os.walk(source): + for f in sorted(filenames): + path = os.path.join(dirpath, f) + destination = os.path.join( + prefix, os.path.join(*path.split(os.path.sep)[1:]) + ) + print(f"{path} -> {destination}") + text = open(path, "r").read() + results["files"][destination] = text + +with open("typeshed.json", "w") as f: + f.write(json.dumps(results, indent=2)) diff --git a/config/pyrightconfig.json b/config/pyrightconfig.json new file mode 100644 index 0000000..eb9f9bb --- /dev/null +++ b/config/pyrightconfig.json @@ -0,0 +1,9 @@ +{ + "pythonVersion": "3.6", + "pythonPlatform": "Linux", + "typeCheckingMode": "basic", + "typeshedPath": "/typeshed/", + "reportMissingModuleSource": false, + "reportWildcardImportFromLibrary": false, + "verboseOutput": true + } diff --git a/discrepancies.md b/discrepancies.md new file mode 100644 index 0000000..83a1c9c --- /dev/null +++ b/discrepancies.md @@ -0,0 +1,116 @@ +# Notes + +These are working notes on discrepancies found when creating these stubs. + +## Cross-cutting issues + +Module docs throughout are a bit arbitrary and need review. + +Various docs don't line up exactly because @overload is the best way to represent their typings so requires docs to be customised for each scenario. + +## Module-specific issues + +### gc + +isenabled is undocumented in MicroPython docs (not added). + +### audio + +[AudioFrame.copyfrom](https://github.com/microbit-foundation/micropython-microbit-v2/blob/bca4dc5690998e8e5de07019a44185fc9b9ea080/src/codal_port/modaudio.c#L301) is undocumented (not added). + +AudioFrame implements some operations that aren't clearly documented (e.g. you can add them, multiple by an integer). I added stubs for these as they're used in examples. + +### uart + +uart.readinto is misindented in the docs (minor). +there's a method documented as having been removed so I've omitted it from the stubs + +### microbit + +- image - type of buffer in second __init__ option +- text modified to split across __init__ definitions +- "Same as" language is unhelpful. +- __sub__ and __div__ added based on examples but not in docs. +- microphone - the doc style here is a bit different to elsewhere, might be less good in Pyright? + +### micropython + +- schedule is undocumented (I've not added it) +- micropython.schedule is missing from our docs. Why? It is on the device (checked on V2). + +### neopixel + +Has long but important module docstring with important warnings for the user. +I've removed the images and reproduced it otherwise in full. + +Some complication with write/show. Fine for stubs but will need revisiting for docs. + +ws2812_write is undocumented (here and in microbit module) +ORDER is undocumented + +### pins (in microbit) + +get_analog_period_microseconds isn't documented + +pin_logo isn't really a pin... it just has: + CAPACITIVE + RESISTIVE + is_touched + set_touch_mode +how to model this? currently incorrectly a touch pin. + +pins need class docs + +NO_PULL etc. aren't available on MicroBitDigitalPin. You need to use the instances +to access. Can/should we model this? + +### machine + + mem16 + mem32 + mem8 +are undocumented + +### os + +ilistdir and stat are undocumented (not added) + +### radio + +In the docs and stubs but not on a V2 (V1 not checked): + +``` +>>> radio.RATE_250KBIT +Traceback (most recent call last): + File "", line 1, in +AttributeError: 'module' object has no attribute 'RATE_250KBIT' +``` + +It's commented out in the source: https://github.com/microbit-foundation/micropython-microbit-v2/blame/eba8995843ebc7246765b364710543c9ffee344a/src/codal_port/modradio.c#L269 + +I've added a note to the docstring for now. + +### microphone + +```python +>>> from microbit import * +>>> repr(microphone.current_event()) +'None' +>>> repr(microphone.current_event()) +"SoundEvent('loud')" +``` + +but [docs](https://microbit-micropython.readthedocs.io/en/v2-docs/microphone.html#microbit.microphone.current_event) (and for now stubs) claim it cannot return None + +Raised https://github.com/microbit-foundation/micropython-microbit-v2/issues/86 + +## Interesting code failures + +In waveforms.py + +```python +frames = [ None ] * 32 +``` + +...is a problematic initialization pattern for arrays. Can we relax the rules? +Is the pattern widespread? What options does Pyright have to relax behaviour around None? diff --git a/examples/micropython/LICENSE b/examples/micropython/LICENSE new file mode 100644 index 0000000..6212290 --- /dev/null +++ b/examples/micropython/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2013-2016 The MicroPython-on-micro:bit Developers, as listed +in the accompanying AUTHORS file + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/examples/micropython/analog_watch.py b/examples/micropython/analog_watch.py new file mode 100644 index 0000000..2484520 --- /dev/null +++ b/examples/micropython/analog_watch.py @@ -0,0 +1,35 @@ +from microbit import * + +hands = Image.ALL_CLOCKS + +#A centre dot of brightness 2. +ticker_image = Image("2\n").crop(-2,-2,5,5) + +#Adjust these to taste +MINUTE_BRIGHT = 0.1111 +HOUR_BRIGHT = 0.55555 + +#Generate hands for 5 minute intervals +def fiveticks(): + fivemins = 0 + hours = 0 + while True: + yield hands[fivemins]*MINUTE_BRIGHT + hands[hours]*HOUR_BRIGHT + fivemins = (fivemins+1)%12 + hours = (hours + (fivemins == 0))%12 + +#Generate hands with ticker superimposed for 1 minute intervals. +def ticks(): + on = True + for face in fiveticks(): + for i in range(5): + if on: + yield face + ticker_image + else: + yield face - ticker_image + on = not on + +#Run a clock speeded up 60 times, so we can watch the animation. +for tick in ticks(): + display.show(tick) + sleep(1000) diff --git a/examples/micropython/asmleds.py.todo b/examples/micropython/asmleds.py.todo new file mode 100644 index 0000000..fef507a --- /dev/null +++ b/examples/micropython/asmleds.py.todo @@ -0,0 +1,57 @@ +""" +This script uses the inline assembler to make the LEDs light up +in a pattern based on how they are multiplexed in rows/cols. +""" + +# row pins: 13, 14, 15 +# col pins: 4..12 inclusive +# GPIO words starting at 0x50000500: +# RESERVED, OUT, OUTSET, OUTCLR, IN, DIR, DIRSET, DIRCLR + +@micropython.asm_thumb +def led_cycle(): + b(START) + + # DELAY routine + label(DELAY) + mov(r3, 0xa0) + lsl(r3, r3, 11) + label(delay_loop) + sub(r3, 1) + bne(delay_loop) + bx(lr) + + label(START) + + cpsid('i') # disable interrupts so we control the display + + mov(r0, 0x50) # r0=0x50 + lsl(r0, r0, 16) # r0=0x500000 + add(r0, 0x05) # r0=0x500005 + lsl(r0, r0, 8) # r0=0x50000500 -- this points to GPIO registers + mov(r1, 0b111) + lsl(r1, r1, 13) # r1=0xe000 + str(r1, [r0, 8]) # pull all rows high + + mov(r1, 1 << 4) # r1 holds current col bit + mov(r2, 9) # r2 holds number of cols left + label(loop_on) + str(r1, [r0, 12]) # pull col low to turn LEDs on + bl(DELAY) # wait + lsl(r1, r1, 1) # shift to next col + sub(r2, 1) # decrease col counter + bne(loop_on) # loop while there are still cols left + + mov(r1, 1 << 4) # r1 holds current col bit + mov(r2, 9) # r2 holds number of cols left + label(loop_off) + str(r1, [r0, 8]) # pull col high to turn LEDs off + bl(DELAY) # wait + lsl(r1, r1, 1) # shift to next col + sub(r2, 1) # decrease col counter + bne(loop_off) # loop while there are still cols left + + cpsie('i') # enable interrupts + +for i in range(4): + led_cycle() diff --git a/examples/micropython/bubble_level_2d.py b/examples/micropython/bubble_level_2d.py new file mode 100755 index 0000000..d6da20a --- /dev/null +++ b/examples/micropython/bubble_level_2d.py @@ -0,0 +1,28 @@ +""" +Two-dimensional bubble level which uses the accelerometer. +""" + +from microbit import * + +sensitivity = "medium" # Change to 'low', 'medium', or 'high' to adjust +divisors = {"low": 64, "medium": 32, "high": 16} + + +def clamp(number, min, max): + """Returns number limited to range specified by min and max, inclusive""" + if number < min: + return min + elif number > max: + return max + else: + return number + + +while True: + x_grav, y_grav, _ = accelerometer.get_values() + # Map raw values from accelerometer to pixels on display + x_pixel = 4 - clamp(2 + x_grav // divisors.get(sensitivity), 0, 4) # type: ignore + y_pixel = 4 - clamp(2 + y_grav // divisors.get(sensitivity), 0, 4) # type: ignore + display.clear() + display.set_pixel(x_pixel, y_pixel, 9) + sleep(100) diff --git a/examples/micropython/compass.py b/examples/micropython/compass.py new file mode 100644 index 0000000..a6b47ec --- /dev/null +++ b/examples/micropython/compass.py @@ -0,0 +1,21 @@ +""" + compass.py + ~~~~~~~~~~ + + Creates a compass. + + The user will need to calibrate the compass first. The compass uses the + built-in clock images to display the position of the needle. + +""" +from microbit import * + + +# Start calibrating +compass.calibrate() + +# Try to keep the needle pointed in (roughly) the correct direction +while True: + sleep(100) + needle = ((15 - compass.heading()) // 30) % 12 + display.show(Image.ALL_CLOCKS[needle]) diff --git a/examples/micropython/conway.py b/examples/micropython/conway.py new file mode 100644 index 0000000..49bd07c --- /dev/null +++ b/examples/micropython/conway.py @@ -0,0 +1,58 @@ +''' +Conway's Game Of Life for the micro:bit + +Press button A or tap the micro:bit to generate a fresh layout. +''' + +import microbit +import random + +arena1 = bytearray(7 * 7) +arena2 = bytearray(7 * 7) + +def show(): + img = microbit.Image(5,5) + for y in range(5): + for x in range(5): + img.set_pixel(x, y, arena1[8 + y * 7 + x]*9) + microbit.display.show(img) + +# do 1 iteration of Conway's Game of Life +def conway_step(): + global arena1, arena2 + for i in range(5 * 5): # loop over pixels + i = 8 + (i // 5) * 7 + i % 5 + # count number of neighbours + num_neighbours = (arena1[i - 8] + + arena1[i - 7] + + arena1[i - 6] + + arena1[i - 1] + + arena1[i + 1] + + arena1[i + 6] + + arena1[i + 7] + + arena1[i + 8]) + # check if the centre cell is alive or not + self = arena1[i] + # apply the rules of life + if self and not (2 <= num_neighbours <= 3): + arena2[i] = 0 # not enough, or too many neighbours: cell dies + elif not self and num_neighbours == 3: + arena2[i] = 1 # exactly 3 neighbours around an empty cell: cell is born + else: + arena2[i] = self # stay as-is + # swap the buffers (arena1 is now the new one to display) + arena1, arena2 = arena2, arena1 + +while True: + # randomise the start + for i in range(5 * 5): # loop over pixels + i = 8 + (i // 5) * 7 + i % 5 + arena1[i] = random.randrange(2) # set the pixel randomly + show() + microbit.sleep(1) # need to yield to update accelerometer (not ideal...) + + # loop while button a is not pressed + while not microbit.button_a.is_pressed() and microbit.accelerometer.get_z() < -800: + conway_step() + show() + microbit.sleep(150) diff --git a/examples/micropython/counter.py b/examples/micropython/counter.py new file mode 100644 index 0000000..f9f7899 --- /dev/null +++ b/examples/micropython/counter.py @@ -0,0 +1,14 @@ +""" + counter.py + ~~~~~~~~~~ + Creates a counter that increments on pressing button a. + Scrolls the current count on the led display. +""" + +import microbit +ctr = 0 # Initialize counter +while True: # Loop forever + ctr = ctr + microbit.button_a.get_presses() # Count the amount of presses + if ctr > 0: # Only execute if not zero + microbit.display.scroll(str(ctr)) # Display the counter + microbit.sleep(100) # Sleep for 100ms diff --git a/examples/micropython/digital_water.py b/examples/micropython/digital_water.py new file mode 100644 index 0000000..a351e2c --- /dev/null +++ b/examples/micropython/digital_water.py @@ -0,0 +1,119 @@ +""" +Digital Water - your micro water simulator. By Tom Viner + +Explanation and see running: +https://www.youtube.com/watch?v=OBTUjoc46Pk +""" + +import microbit + +# define some constants + +DISPLAY_WIDTH = 5 +DISPLAY_HEIGHT = 5 + +MIN_BRIGHTNESS = 0 +MEDIUM_BRIGHTNESS = 4 +MAX_BRIGHTNESS = 9 + +# this is how the accelerometer values 1g of gravity +ONE_G = 1024 + +# Some maths functions to help us + +def clamp(minimum, n, maximum): + """Return the nearest value to n, that's within minimum to maximum (incl) + """ + return max(minimum, min(n, maximum)) + +def rescale(src_scale, dest_scale, x): + """Map one number scale to another + + For example, to convert a score of 4 stars out of 5 into a percentage: + >>> rescale((0, 5), (0, 100), 4) + 80.0 + + Great for mapping different input values into LED pixel brightnesses! + """ + src_start, src_end = src_scale + # what proportion along src_scale x is: + proportion = 1.0 * (x - src_start) / (src_end - src_start) + + dest_start, dest_end = dest_scale + # apply our proportion to the dest_scale + return proportion * (dest_end - dest_start) + dest_start + +# Helpers for controling the display + +def light(brightness, filter): + """Light up all pixels matching the filter function + """ + brightness = clamp(MIN_BRIGHTNESS, round(brightness), MAX_BRIGHTNESS) + for col in range(DISPLAY_WIDTH): + for row in range(DISPLAY_HEIGHT): + if filter(col, row): + microbit.display.set_pixel(col, row, brightness) + +def fade_display(): + """Reduce every pixel by 1 brightness level + + This means as we draw new things, the old ones will fade away + """ + for col in range(5): + for row in range(5): + brightness = microbit.display.get_pixel(col, row) + # reduce by one, but make sure it's still in 0 to 9 + brightness = clamp(MIN_BRIGHTNESS, brightness - 1, MAX_BRIGHTNESS) + microbit.display.set_pixel(col, row, brightness) + + +def paint_water(): + """Use the accelerometer to paint a water level on the display + """ + # read the current orientation values from the accelerometer + X, Y, Z = microbit.accelerometer.get_values() + + # map the force in the X-axis to a turn factor from -2 to 2 + # -ONE_G is button A at the top, ONE_G is button B at the top + turn_factor = rescale((-ONE_G, ONE_G), (-2, 2), X) + + # map the force in the Z-axis to a spill factor from -3 to 3 + # this allows the water to cover the whole display when it's flat + spill_factor = rescale((ONE_G, -ONE_G), (-3, 3), Z) + + # use the variables above to make a filter function, customised for the + # current orientation of the micro:bit + def filter(col, row): + """For a given pixel position, decide if it should be on or not + """ + if Y < 0: + # we're upside down, so reverse the y-axis value + # (- 1 because we start counting rows from 0, not 1) + row = DISPLAY_HEIGHT - 1 - row + # remember rows count down from the top, so we want to light up all + # the rows below the water line (when the micro:bit is help up straight) + # The forumula here is of the form y = m*x + c + # We have a couple of "- 2"s to centre the water level in the middle + # of the display + return row - 2 > -turn_factor * (col - 2) - spill_factor + + # we want the water to "dilute" when spread out across the whole display + overall_brightness = rescale( + (0, ONE_G), + (MAX_BRIGHTNESS, MEDIUM_BRIGHTNESS), + abs(Z) + ) + + # light up the pixels when filter returns true, to the given bright level + light(overall_brightness, filter) + +# loop forever painting watery pixels, sleeping and then fading as each pixel +# washes away into the night + +while True: + paint_water() + + microbit.sleep(100) + + # fade all pixels by one brightness level + fade_display() diff --git a/examples/micropython/dodge_game.py b/examples/micropython/dodge_game.py new file mode 100644 index 0000000..b37ba0e --- /dev/null +++ b/examples/micropython/dodge_game.py @@ -0,0 +1,137 @@ +""" +Dodge game + +Get the player back and forth across the screen while dodging the enemy +""" + +from microbit import * +import music + + +class Enemy: + """ + Enemy which moves vertically down the screen + """ + def __init__(self): + self.x, self.y = 2, -1 + + def get_positions(self): + return ((self.x, self.y), (self.x, self.y + 1 if self.y < 4 else 0)) + + def move(self): + # Rotate back round to the top + self.y = (self.y + 1) % 5 + + def draw(self): + for x, y in self.get_positions(): + display.set_pixel(x, y, 9) + + +class Player: + """ + Left-right moving player which can be controlled with buttons + """ + RIGHT = 1 + LEFT = -1 + STOPPED = 0 + LEFT_EDGE = 0 + RIGHT_EDGE = 4 + + def __init__(self): + self.alive = True + self.score = 0 + self.just_scored = False + self.x, self.y = self.LEFT_EDGE, 2 + self.direction = self.STOPPED + + def get_position(self): + return (self.x, self.y) + + def die(self): + """ + Player dies - show their score and play sad music + """ + self.alive = False + display.show(str(self.score)) + music.play(music.WAWAWAWAA) + + def move(self): + """ + Move the player one step further in their + current direction + """ + self.just_scored = False + self.x += self.direction + if self.x in (self.LEFT_EDGE, self.RIGHT_EDGE): + # Player reached the edge - another run survived! + if self.direction != self.STOPPED: + self.score += 1 + self.just_scored = True + + self.direction = self.STOPPED + + def draw(self): + """ + Draw the player + """ + display.set_pixel(self.x, self.y, 9) + if self.just_scored: + music.pitch(400, 40) + + def act_on_input(self): + # If we're standing still, look for a button press. + if self.direction == self.STOPPED: + if button_b.was_pressed() and self.x == self.LEFT_EDGE: + self.direction = self.RIGHT + + elif button_a.was_pressed() and self.x == self.RIGHT_EDGE: + self.direction = self.LEFT + + +class Game: + def __init__(self): + self.enemy = Enemy() + self.player = Player() + self.frame_rate = 1 + + def detect_collisions(self): + """ + Have the player and the enemy collided? + """ + return self.player.get_position() in self.enemy.get_positions() + + def do_frame(self): + """ + Called once per frame to advance the game state + """ + # Adjust the speed as the player's score gets higher + # (But don't let it exceed the actual frame rate) + self.frame_rate = max(1, min(100, self.player.score)) + + if self.player.alive: + display.clear() + + self.enemy.move() + self.player.act_on_input() + self.player.move() + + if self.detect_collisions(): + self.player.die() + else: + self.enemy.draw() + self.player.draw() + + +game = Game() +while True: + timestamp = running_time() + + game.do_frame() + + # Keep the frame rate consistent + new_timestamp = running_time() + time_taken = (new_timestamp - timestamp) + interval = 1000 // game.frame_rate + if time_taken < interval: + sleep(interval - time_taken) + timestamp = new_timestamp diff --git a/examples/micropython/flame_simulation.py b/examples/micropython/flame_simulation.py new file mode 100644 index 0000000..e7c45c4 --- /dev/null +++ b/examples/micropython/flame_simulation.py @@ -0,0 +1,102 @@ +### Flame simulation on the Microbit. +### Author: M. Schafer 2016 +# This program has been placed into the public domain. + +import microbit, random + +# User adjustable values for range of brightness in flames. +MIN_BRIGHTNESS = 1 +MAX_BRIGHTNESS = 8 + + +# fixed for the Microbit +DISPLAY_WIDTH = 5 +DISPLAY_HEIGHT = 5 + +INVERT_DISPLAY = True # flame can be oriented in either direction + +# MASK to create fire shape. multiplies values % +MASK = [[ 88, 100, 100, 100, 88 ], + [ 60, 95, 100, 95, 60 ], + [ 50, 88, 90, 88, 50 ], + [ 33, 75, 88, 75, 33 ], + [ 10, 33, 66, 33, 10 ] ] + +# Generate a new bottom row of random values for the flames +def generate_line(start=MIN_BRIGHTNESS, end=MAX_BRIGHTNESS): + "start and end define range of dimmest to brightest 'flames'" + return [start + random.randrange(end-start) for i in range(DISPLAY_WIDTH)] + +# shift all values in the grid up one row +def shift_up(grid, newline): + "Shift up lines in grid, add newline at bottom" + for y in range(DISPLAY_HEIGHT-1, 0, -1): + grid[y] = grid[y-1] + # lowest line + for x in range(DISPLAY_WIDTH): + grid[0] = newline + + +# write a frame to the screen. +# Interpolate values based on percent +def interpolate_frame(screen, pcnt, grid, line): + """ Interpolate new values by reading from grid and + writing to the screen """ + # each row interpolates with the one before it + for y in range(DISPLAY_HEIGHT-1, 0, -1): + for x in range(DISPLAY_WIDTH): + mask = MASK[y][x] + newval = ((100-pcnt) * grid[y][x] + pcnt * grid[y-1][x] ) / 100.0 + newval = mask * newval / 100.0 + if INVERT_DISPLAY: + screen.set_pixel(x, DISPLAY_HEIGHT-y-1, int(newval)) + else: + screen.set_pixel(x, y, int(newval)) + # first row interpolates with the "next" line + for x in range(DISPLAY_WIDTH): + mask = MASK[y][x] # type: ignore + newval = ((100-pcnt) * grid[0][x] + pcnt * line[x]) / 100.0 + newval = mask * newval / 100.0 + if INVERT_DISPLAY: + screen.set_pixel(x, DISPLAY_HEIGHT-1, int(newval)) + else: + screen.set_pixel(x, 0, int(newval)) + +## Setup + +line = generate_line() +grid = [[0 for i in range(DISPLAY_WIDTH)] for i in range(DISPLAY_HEIGHT)] + +SCREEN = microbit.display +percent = 0 # counter to see when to re-interpolate +sleeptime = 0 # delay between updates +percent_increment = 25 # how fast we interpolate fire + + +# loop forever +while True: + if percent > 100: + # move everything up a line, insert new bottom row + line = generate_line() + shift_up(grid, line) + percent = 0 + + # Check Buttons to see if changing + # button_a = smoothness + if microbit.button_a.was_pressed(): + percent_increment += 5 + if percent_increment > 50: + percent_increment = 1 + print("percent interpolate=", percent_increment) + # button_b = delay + if microbit.button_b.was_pressed(): + sleeptime += 10 + if sleeptime > 100: + sleeptime = 0 + print("sleeptime=", sleeptime) + # draw frame and sleep + interpolate_frame(SCREEN, percent, grid, line) + microbit.sleep(sleeptime) + # update main counters + percent += percent_increment + diff --git a/examples/micropython/flappybit.py b/examples/micropython/flappybit.py new file mode 100644 index 0000000..9b0eac2 --- /dev/null +++ b/examples/micropython/flappybit.py @@ -0,0 +1,77 @@ +''' +Flappy Bit + +Control the bit by tilting the micro:bit + +Avoid the obstacles + +Create your own terrain by editing the terrain list below: +''' + +import music +from microbit import (accelerometer, + display, + sleep, + Image, + reset, + ) + +display.scroll('Flappy Bit') + +bird = 2 +terrain = [ + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 2), + (0, 0), + (0, 0), + (3, 0), + (3, 0), + (4, 0), + (3, 0), + (0, 0), + (0, 0), + (0, 1), + (2, 0), + (3, 0), + (4, 0), + (3, 0), + (0, 0), + (0, 1), + (2, 0), +] + +terrain_multiplier = 5 +pos = 0 + +while True: + sleep(100) + if -256 < accelerometer.get_y() < 450: + bird = max(0, bird - 1) + elif 568 < accelerometer.get_y() < 1024: + bird = min(4, bird + 1) + + display.clear() + display.set_pixel(0, bird, 9) + + pos_terrain = pos // terrain_multiplier + lost_status = False + for column, (top, bottom) in enumerate( + terrain[pos_terrain:pos_terrain + 5]): + for y in range(top): + display.set_pixel(column, y, 4) + if column == 0 and bird == y: + lost_status = True + for y in range(bottom): + display.set_pixel(column, 4 - y, 4) + if column == 0 and bird == (4 - y): + lost_status = True + if lost_status: + display.show(Image.SAD) + music.play(music.FUNERAL) + reset() + pos += 1 + if pos_terrain > len(terrain): + pos = 0 diff --git a/examples/micropython/four_buttons.py b/examples/micropython/four_buttons.py new file mode 100644 index 0000000..c794d3b --- /dev/null +++ b/examples/micropython/four_buttons.py @@ -0,0 +1,120 @@ +"""Four buttons - 2 buttons + 2 more "buttons"! +A little example of using pins 1 & 2 an extra 2 buttons. By Tom Viner + +Explanation and see running: +https://www.youtube.com/watch?v=6ofUJ6Mgk4k +""" +import microbit + +# define some constants + +DISPLAY_WIDTH = 5 +DISPLAY_HEIGHT = 5 + +MIN_BRIGHTNESS = 0 +MAX_BRIGHTNESS = 9 + +# A maths functions to help us + +def clamp(minimum, n, maximum): + """Return the nearest value to n, that's within minimum to maximum (incl) + """ + return max(minimum, min(n, maximum)) + + +# Helpers for controling the display + +def light(brightness, filter): + """Light up all pixels matching the filter function + """ + brightness = clamp(MIN_BRIGHTNESS, round(brightness), MAX_BRIGHTNESS) + for col in range(DISPLAY_WIDTH): + for row in range(DISPLAY_HEIGHT): + if filter(col, row): + microbit.display.set_pixel(col, row, brightness) + +def light_column(column): + """Light up a whole column to max brightness + """ + def filter_column(col, row): + """For a given pixel position, turn on if it matches our column + """ + return col == column + light(MAX_BRIGHTNESS, filter_column) + +def light_row(row): + """Light up a whole row to max brightness + """ + def filter_row(col, rw): + """For a given pixel position, turn on if it matches our row + """ + return rw == row + light(MAX_BRIGHTNESS, filter_row) + +def fade_display(): + """Reduce every pixel by 1 brightness level + + This means as we draw new things, the old ones will fade away + """ + for col in range(5): + for row in range(5): + brightness = microbit.display.get_pixel(col, row) + # reduce by one, but make sure it's still in 0 to 9 + brightness = clamp(MIN_BRIGHTNESS, brightness - 1, MAX_BRIGHTNESS) + microbit.display.set_pixel(col, row, brightness) + +def paint_box(top=0, bottom=DISPLAY_HEIGHT-1, left=0, right=DISPLAY_WIDTH-1): + """Draw a filled in rectangle on the display + """ + def filter_box(col, row): + """For a given pixel position, turn it on if it's with the bounds + """ + # remember rows count from 0 at the top! + correct_vertical = top <= row <= bottom + correct_horizontal = left <= col <= right + return correct_vertical and correct_horizontal + light(MAX_BRIGHTNESS, filter_box) + + +# Our main functions + +def pin_is_touched(n): + """Pass in a pin number (1 or 2), + get back True if it's being touched right now + + In this way, it acts just like microbit.button_a.is_pressed() + """ + pin = getattr(microbit, 'pin{}'.format(n)) + return pin.read_analog() > 300 + +def four_buttons(): + """Push buttons, touch pins, see if you can light up the whole display! + """ + a_is_pressed = microbit.button_a.is_pressed() + b_is_pressed = microbit.button_b.is_pressed() + + # let's call the two pin-buttons c and d: + c_is_pressed = pin_is_touched(1) + d_is_pressed = pin_is_touched(2) + + if a_is_pressed: + light_row(2) + paint_box(right=1) + if b_is_pressed: + light_row(3) + paint_box(left=3) + if c_is_pressed: + light_column(1) + paint_box(bottom=1) + if d_is_pressed: + light_column(3) + paint_box(top=3) + + +while True: + four_buttons() + + microbit.sleep(10) + + # fade all pixels by one brightness level + fade_display() diff --git a/examples/micropython/i_feel_today.py b/examples/micropython/i_feel_today.py new file mode 100755 index 0000000..d1b2972 --- /dev/null +++ b/examples/micropython/i_feel_today.py @@ -0,0 +1,20 @@ +""" +Program that shows different emotions. +Push button "A" to become sadder and "B" to become happier. +""" + +from microbit import * + +horror = Image("09090:00000:09990:90009:99999") +better_meh = Image("00000:09090:00000:99999:00000") +joy = Image("09090:00000:99999:90009:09990") + +emotions = [horror, Image.SAD, better_meh, Image.HAPPY, joy] +current_emotion = 2 + +while True: + if button_a.get_presses(): + current_emotion = max(current_emotion - 1, 0) + elif button_b.get_presses(): + current_emotion = min(current_emotion + 1, 4) + display.show(emotions[current_emotion]) \ No newline at end of file diff --git a/examples/micropython/led_dance.py b/examples/micropython/led_dance.py new file mode 100644 index 0000000..8718083 --- /dev/null +++ b/examples/micropython/led_dance.py @@ -0,0 +1,25 @@ +# Light LEDs at random and make them fade over time +# +# Usage: +# +# led_dance(delay) +# +# 'delay' is the time between each new LED being turned on. +# +# TODO The random number generator is not great. Perhaps the accelerometer +# or compass could be used to add entropy. + +import microbit +import random + +def led_dance(delay): + dots = [ [0]*5, [0]*5, [0]*5, [0]*5, [0]*5 ] + while True: + dots[random.randrange(5)][random.randrange(5)] = 8 + for i in range(5): + for j in range(5): + microbit.display.set_pixel(i, j, dots[i][j]) + dots[i][j] = max(dots[i][j] - 1, 0) + microbit.sleep(delay) + +led_dance(100) diff --git a/examples/micropython/magic8.py b/examples/micropython/magic8.py new file mode 100644 index 0000000..d8baf81 --- /dev/null +++ b/examples/micropython/magic8.py @@ -0,0 +1,38 @@ +# Magic 8 ball by Nicholas Tollervey. February 2016. +# +# Ask a question then shake. +# +# This program has been placed into the public domain. +from microbit import * +import random + +answers = [ + "It is certain", + "It is decidedly so", + "Without a doubt", + "Yes, definitely", + "You may rely on it", + "As I see it, yes", + "Most likely", + "Outlook good", + "Yes", + "Signs point to yes", + "Reply hazy try again", + "Ask again later", + "Better not tell you now", + "Cannot predict now", + "Concentrate and ask again", + "Don't count on it", + "My reply is no", + "My sources say no", + "Outlook not so good", + "Very doubtful", +] + +while True: + display.show('8') + if accelerometer.was_gesture('shake'): + display.clear() + sleep(1000) + display.scroll(random.choice(answers)) + sleep(10) diff --git a/examples/micropython/maze.py b/examples/micropython/maze.py new file mode 100644 index 0000000..9fb56f4 --- /dev/null +++ b/examples/micropython/maze.py @@ -0,0 +1,73 @@ +""" +A simple maze program. You are the flashing dot and can walk around +using the accelerometer. +""" + +import microbit + +d = microbit.display +ac = microbit.accelerometer + +# the maze data, as binary numbers (outside walls are added automatically) +maze = [ + 0b0000000000000000, + 0b0100010101011110, + 0b0100010101010010, + 0b0111110100000000, + 0b0000000111111110, + 0b0111111101000000, + 0b0101010001011100, + 0b0101000100000100, + 0b0100011111111100, + 0b0101010001000110, + 0b0101000100010010, + 0b0101010111010110, + 0b0111010101010010, + 0b0000010100010010, + 0b0111110111111110, + 0b0000000000000000, +] + +def get_maze(x, y): + if 0 <= x < 16 and 0 <= y < 16: + return (maze[y] >> (15 - x)) & 1 + else: + return 1 + +def draw(x, y, tick): + img = microbit.Image(5,5) + for j in range(5): + for i in range(5): + img.set_pixel(i, j, get_maze(x + i - 2, y + j - 2)*5) + + # draw the player, flashing + img.set_pixel(2, 2, (tick & 1)*4+5) + d.show(img) + +def main(): + x = 0 + y = 0 + tick = 0 + while True: + tick += 1 + if tick == 4: + # walk around, with collision detection + tick = 0 + if ac.get_x() > 200 and get_maze(x + 1, y) == 0: + x += 1 + elif ac.get_x() < -200 and get_maze(x - 1, y) == 0: + x -= 1 + elif ac.get_y() > 200 and get_maze(x, y + 1) == 0: + y += 1 + elif ac.get_y() < -200 and get_maze(x, y - 1) == 0: + y -= 1 + x = min(15, max(0, x)) + y = min(15, max(0, y)) + + # draw the maze + draw(x, y, tick) + + + microbit.sleep(50) + +main() diff --git a/examples/micropython/music.py b/examples/micropython/music.py new file mode 100644 index 0000000..e013448 --- /dev/null +++ b/examples/micropython/music.py @@ -0,0 +1,27 @@ +""" + music.py + ~~~~~~~~ + + Plays a simple tune using the Micropython music module. + This example requires a speaker/buzzer/headphones connected to P0 and GND, + or the latest micro:bit device with built-in speaker. +""" +from microbit import * +import music + +# play Prelude in C. +notes = [ + 'c4:1', 'e', 'g', 'c5', 'e5', 'g4', 'c5', 'e5', 'c4', 'e', 'g', 'c5', 'e5', 'g4', 'c5', 'e5', + 'c4', 'd', 'a', 'd5', 'f5', 'a4', 'd5', 'f5', 'c4', 'd', 'a', 'd5', 'f5', 'a4', 'd5', 'f5', + 'b3', 'd4', 'g', 'd5', 'f5', 'g4', 'd5', 'f5', 'b3', 'd4', 'g', 'd5', 'f5', 'g4', 'd5', 'f5', + 'c4', 'e', 'g', 'c5', 'e5', 'g4', 'c5', 'e5', 'c4', 'e', 'g', 'c5', 'e5', 'g4', 'c5', 'e5', + 'c4', 'e', 'a', 'e5', 'a5', 'a4', 'e5', 'a5', 'c4', 'e', 'a', 'e5', 'a5', 'a4', 'e5', 'a5', + 'c4', 'd', 'f#', 'a', 'd5', 'f#4', 'a', 'd5', 'c4', 'd', 'f#', 'a', 'd5', 'f#4', 'a', 'd5', + 'b3', 'd4', 'g', 'd5', 'g5', 'g4', 'd5', 'g5', 'b3', 'd4', 'g', 'd5', 'g5', 'g4', 'd5', 'g5', + 'b3', 'c4', 'e', 'g', 'c5', 'e4', 'g', 'c5', 'b3', 'c4', 'e', 'g', 'c5', 'e4', 'g', 'c5', + 'a3', 'c4', 'e', 'g', 'c5', 'e4', 'g', 'c5', 'a3', 'c4', 'e', 'g', 'c5', 'e4', 'g', 'c5', + 'd3', 'a', 'd4', 'f#', 'c5', 'd4', 'f#', 'c5', 'd3', 'a', 'd4', 'f#', 'c5', 'd4', 'f#', 'c5', + 'g3', 'b', 'd4', 'g', 'b', 'd', 'g', 'b', 'g3', 'b3', 'd4', 'g', 'b', 'd', 'g', 'b' +] + +music.play(notes) diff --git a/examples/micropython/neopixel_random.py b/examples/micropython/neopixel_random.py new file mode 100644 index 0000000..ad8af0d --- /dev/null +++ b/examples/micropython/neopixel_random.py @@ -0,0 +1,28 @@ +""" + neopixel_random.py + + Repeatedly displays random colours onto the LED strip. + This example requires a strip of 8 Neopixels (WS2812) connected to pin0. + +""" +from microbit import * +import neopixel +from random import randint + +# Setup the Neopixel strip on pin0 with a length of 8 pixels +np = neopixel.NeoPixel(pin0, 8) + +while True: + #Iterate over each LED in the strip + + for pixel_id in range(0, len(np)): + red = randint(0, 60) + green = randint(0, 60) + blue = randint(0, 60) + + # Assign the current LED a random red, green and blue value between 0 and 60 + np[pixel_id] = (red, green, blue) + + # Display the current pixel data on the Neopixel strip + np.show() + sleep(100) diff --git a/examples/micropython/play_file.py b/examples/micropython/play_file.py new file mode 100644 index 0000000..2a014fc --- /dev/null +++ b/examples/micropython/play_file.py @@ -0,0 +1,14 @@ +#Plays a file on the specified pins. +import audio + +def audio_generator(file, frame): + ln = -1 + while ln: + ln = file.readinto(frame) + yield frame + +def play_file(name, pin=None, return_pin=None): + #Do allocation here, as we can't do it in an interrupt. + frame = audio.AudioFrame() + with open(name) as file: + audio.play(audio_generator(file, frame), pin=pin, return_pin=return_pin) diff --git a/examples/micropython/pomodoro.py b/examples/micropython/pomodoro.py new file mode 100644 index 0000000..3a1d28e --- /dev/null +++ b/examples/micropython/pomodoro.py @@ -0,0 +1,67 @@ +""" +A simple pomodoro timer. +It times a 25 minute work session then 5 minutes rest. +Press the reset button to restart the timer. +""" + +from microbit import * + +# Tweak CLOCK_ADJUST to make your system clock more accurate. +# My clock is too fast by 4 seconds every minute so I use 4/60. +# If your clock is too slow by 3 seconds every minute use -3/60. + +CLOCK_ADJUST = 4/60 + +ALL_LEDS_ON = Image('99999:'*5) + + +def index_to_xy(i): + x = i % 5 + y = int(i / 5) + return x, y + + +def show_alarm(): + for i in range(10): + display.show(ALL_LEDS_ON) + sleep(250) + display.clear() + sleep(250) + + +def run_timer(seconds, LED_state): + interval = int(seconds * 1000 / 25 * (1 + CLOCK_ADJUST)) + intervals_remaining = 25 + timer = running_time() + + while intervals_remaining > 0: + + # Every interval set a pixel to LED_state + time = running_time() + if time - timer >= interval: + timer = time + x, y = index_to_xy(intervals_remaining - 1) + display.set_pixel(x, y, LED_state) + intervals_remaining -= 1 + + +print("pomodoro timer") + + +# time the pomodoro work session, 25 minutes +display.scroll("Go!") +display.show(ALL_LEDS_ON) +run_timer(25 * 60, 0) +show_alarm() + + +# time the pomodoro break, 5 minutes +display.scroll("break") +display.clear() +run_timer(5 * 60, 1) +show_alarm() + +display.show(Image.NO) + +print("finished\n") +print("Press the reset button to restart timer.") diff --git a/examples/micropython/radio.py b/examples/micropython/radio.py new file mode 100644 index 0000000..1cb0226 --- /dev/null +++ b/examples/micropython/radio.py @@ -0,0 +1,30 @@ +# A micro:bit Firefly. +# By Nicholas H.Tollervey. Released to the public domain. +import radio +import random +from microbit import display, Image, button_a, sleep + +# Create the "flash" animation frames. Can you work out how it's done? +flash = [Image().invert()*(i/9) for i in range(9, -1, -1)] + +# The radio won't work unless it's switched on. +radio.on() + +# Event loop. +while True: + # Button A sends a "flash" message. + if button_a.was_pressed(): + radio.send('flash') # a-ha + # Read any incoming messages. + incoming = radio.receive() + if incoming == 'flash': + # If there's an incoming "flash" message display + # the firefly flash animation after a random short + # pause. + sleep(random.randint(50, 350)) + display.show(flash, delay=100, wait=False) + # Randomly re-broadcast the flash message after a + # slight delay. + if random.randint(0, 9) == 0: + sleep(500) + radio.send('flash') # a-ha diff --git a/examples/micropython/reverb.py b/examples/micropython/reverb.py new file mode 100644 index 0000000..b4f4273 --- /dev/null +++ b/examples/micropython/reverb.py @@ -0,0 +1,50 @@ +import audio + +def from_file(file, frame): + ln = -1 + while ln: + ln = file.readinto(frame) + yield frame + +def reverb_gen(src, buckets, reflect, fadeout): + bucket_count = len(buckets) + bucket = 0 + for frame in src: + echo = buckets[bucket] + echo *= reflect + echo += frame + yield echo + buckets[bucket] = echo + bucket += 1 + if bucket == bucket_count: + bucket = 0 + while fadeout: + fadeout -= 1 + echo = buckets[bucket] + echo *= reflect + yield echo + buckets[bucket] = echo + bucket += 1 + if bucket == bucket_count: + bucket = 0 + +def reverb(src, delay, reflect): + #Do all allocation up front, so we don't need to do any in the generator. + bucket_count = delay>>2 + buckets = [ None ] * bucket_count + for i in range(bucket_count): + buckets[i] = audio.AudioFrame() + vol = 1.0 + fadeout = 0 + while vol > 0.05: + fadeout += bucket_count + vol *= reflect + return reverb_gen(src, buckets, reflect, fadeout) + +def play_file(name, delay=80, reflect=0.5): + #Do allocation here, as we can't do it in an interrupt. + frame = audio.AudioFrame() + with open(name) as file: + gen = from_file(file, frame) + r = reverb(gen, delay, reflect) + audio.play(r) diff --git a/examples/micropython/simple_slalom.py b/examples/micropython/simple_slalom.py new file mode 100644 index 0000000..09d6688 --- /dev/null +++ b/examples/micropython/simple_slalom.py @@ -0,0 +1,121 @@ +# Simple Slalom by Larry Hastings, September 2015 +# +# This program has been placed into the public domain. + +import microbit as m +import random + +p = m.display.show + +min_x = -1024 +max_x = 1024 +range_x = max_x - min_x + +wall_min_speed = 400 +player_min_speed = 200 + +wall_max_speed = 100 +player_max_speed = 50 + +speed_max = 12 + + +while True: + + i = m.Image('00000:'*5) + s = i.set_pixel + + player_x = 2 + + wall_y = -1 + hole = 0 + + score = 0 + handled_this_wall = False + + wall_speed = wall_min_speed + player_speed = player_min_speed + + wall_next = 0 + player_next = 0 + + while True: + t = m.running_time() + player_update = t >= player_next + wall_update = t >= wall_next + if not (player_update or wall_update): + next_event = min(wall_next, player_next) + delta = next_event - t + m.sleep(delta) + continue + + if wall_update: + # calculate new speeds + speed = min(score, speed_max) + wall_speed = wall_min_speed + int((wall_max_speed - wall_min_speed) * speed / speed_max) + player_speed = player_min_speed + int((player_max_speed - player_min_speed) * speed / speed_max) + + wall_next = t + wall_speed + if wall_y < 5: + # erase old wall + use_wall_y = max(wall_y, 0) + for wall_x in range(5): + if wall_x != hole: + s(wall_x, use_wall_y, 0) + + wall_reached_player = (wall_y == 4) + if player_update: + player_next = t + player_speed + # find new x coord + x = m.accelerometer.get_x() + x = min(max(min_x, x), max_x) + # print("x accel", x) + s(player_x, 4, 0) # turn off old pixel + x = ((x - min_x) / range_x) * 5 + x = min(max(0, x), 4) + x = int(x + 0.5) + # print("have", position, "want", x) + + if not handled_this_wall: + if player_x < x: + player_x += 1 + elif player_x > x: + player_x -= 1 + # print("new", position) + # print() + + if wall_update: + # update wall position + wall_y += 1 + if wall_y == 7: + wall_y = -1 + hole = random.randrange(5) + handled_this_wall = False + + if wall_y < 5: + # draw new wall + use_wall_y = max(wall_y, 0) + for wall_x in range(5): + if wall_x != hole: + s(wall_x, use_wall_y, 6) + + if wall_reached_player and not handled_this_wall: + handled_this_wall = True + if (player_x != hole): + # collision! game over! + break + score += 1 + + if player_update: + s(player_x, 4, 9) # turn on new pixel + + p(i) + + p(i.SAD) + m.sleep(1000) + m.display.scroll("Score:" + str(score)) + + while True: + if (m.button_a.is_pressed() and m.button_a.is_pressed()): + break + m.sleep(100) diff --git a/examples/micropython/speech.py b/examples/micropython/speech.py new file mode 100644 index 0000000..3abee42 --- /dev/null +++ b/examples/micropython/speech.py @@ -0,0 +1,42 @@ +""" + speech.py + ~~~~~~~~ + + Simple speech example to make the micro:bit say, pronounce and sing + something. This example requires a speaker/buzzer/headphones connected + to P0 and GND,or the latest micro:bit device with built-in speaker. +""" +import speech +from microbit import sleep + +# The say method attempts to convert English into phonemes. +speech.say("I can sing!") +sleep(1000) +speech.say("Listen to me!") +sleep(1000) + +# Clearing the throat requires the use of phonemes. Changing +# the pitch and speed also helps create the right effect. +speech.pronounce("AEAE/HAEMM", pitch=200, speed=100) # Ahem +sleep(1000) + +# Singing requires a phoneme with an annotated pitch for each syllable. +solfa = [ + "#115DOWWWWWW", # Doh + "#103REYYYYYY", # Re + "#94MIYYYYYY", # Mi + "#88FAOAOAOAOR", # Fa + "#78SOHWWWWW", # Soh + "#70LAOAOAOAOR", # La + "#62TIYYYYYY", # Ti + "#58DOWWWWWW", # Doh +] + +# Sing the scale ascending in pitch. +song = ''.join(solfa) +speech.sing(song, speed=100) +# Reverse the list of syllables. +solfa.reverse() +song = ''.join(solfa) +# Sing the scale descending in pitch. +speech.sing(song, speed=100) diff --git a/examples/micropython/tiltmusic.py b/examples/micropython/tiltmusic.py new file mode 100644 index 0000000..3fa7773 --- /dev/null +++ b/examples/micropython/tiltmusic.py @@ -0,0 +1,54 @@ +# TiltMusic by Alex "Chozabu" P-B. September 2016. +# +# Tilt Y to change Pitch +# press A to turn sound on or off +# hold B and tilt X to change the note length +# +# A quick demo can be found at https://youtu.be/vvECQTDiWxQ +# +# This program has been placed into the public domain. + +from microbit import * +import music + +#A selection of sharp notes +notes = [233.08, 277.18, 311.13, 369.99, 415.30, +466.16, 554.37, 622.25, 739.99, 830.61, 932.33, +1108.73, 1244.51, 1479.98, 1661.22, 1864.66, +2217.46, 2489.02, 2959.96, 3322.44, 3729.31, +4434.92, 4978.03, 5919.91, 6644.88, 7458.62] + +#note lengths +note_durations = [ + 50, 100, 200, 400, 800 +] +durationlen = len(note_durations) +notelen = len(notes) + +duration = 100 + +play_music = True + +while True: + #get accelerometer readings + xreading = abs(accelerometer.get_x()) + yreading = abs(accelerometer.get_y()) + + #use a to toggle music + if button_a.was_pressed(): + play_music = not play_music + if not play_music: + continue + + #get a note based on tilt + note = xreading*.01 + pitch = notes[int(note)%notelen] + + #if b is pressed, alter the length based on tilt + if button_b.is_pressed() == 1: + #pitch *= .5 + duration = note_durations[int(yreading*0.01)%durationlen] + + #play our sound! + music.pitch(int(pitch), duration) + diff --git a/examples/micropython/watch.py b/examples/micropython/watch.py new file mode 100644 index 0000000..e9c13c4 --- /dev/null +++ b/examples/micropython/watch.py @@ -0,0 +1,151 @@ +###################################################### +# A watch (as in a small clock for your wrist or pocket) +# +# Button A sets the mode: Clock or Setting time +# Button B +# in clock mode: shows the time as a scrolling display +# in setting mode: increments the time +# +# The LED array displays the clock time in the format hh:mm. +# The digits of the time are represented by columns of LEDs. +# +# The digits 1 - 5 are represented by more LEDs being lit from +# the bottom up. +# +# For instance the digit 3 would look like: +# +# . +# . +# X +# X +# X +# +# +# The digits 6 - 9 are represented by LEDs being turned off from +# the bottom up. The digit 6 would look like: +# +# X +# X +# X +# X +# . +# +# The centre column is a colon flashing once a second to separate hours from minutes. +# +# The time 17:49 would look like: +# +# . X . . X +# . X . X . +# . X . X . +# . . . X . +# X . . X . +# +# +###################################################### + +from microbit import * + +# Tweak CLOCK_ADJUST to make your system clock more accurate. +# My clock is too fast by 4 seconds every minute so I use 4/60. +# If your clock is too slow by 3 seconds every minute use -3/60. +CLOCK_ADJUST = 4/60 + +last_button_a_state = False +last_button_b_state = False +last_display_time = 0 +base_time = 0 +mode = 0 + +modes = {0:"clock", 1:"set h", 2:"mx10", 3:"m"} + + +def decode_time(milliseconds): + """Converts a time in milliseconds into a string with hours:minutes,""" + mins = int(milliseconds / (1000 * 60) % 60) + hrs = int(milliseconds / (1000 * 60 * 60) % 24) + return "{h:0>2}:{m:0>2}".format(h=hrs, m=mins) + + +def show_time(time): + time_string = decode_time(time) + + for i in range(5): + if time_string[i].isdigit(): + d = int(time_string[i]) + plot_LED_column(i, d) + + show_colon(mode==0 and int((time / 1000) % 2)) + + +def show_colon(visible): + display.set_pixel(2, 1, visible*9) + display.set_pixel(2, 3, visible*9) + + +def get_clock_time(): + global base_time + sys_time = running_time() / (1 + CLOCK_ADJUST) + time = (sys_time - base_time) % (24 * 60 * 60 * 1000) + base_time = sys_time - time + return time + + +def plot_LED_column(column, number): + """plots a column of LEDs to represent a number from 0 - 9""" + if number > 9: + number = 9 + + if number <= 5: + for i in range(4, -1, -1): + if i < 5 - number: + display.set_pixel(column, i, 0) + else: + display.set_pixel(column, i, 9) + + if number > 5: + for i in range(4, -1, -1): + if i < 5 - (number - 5): + display.set_pixel(column, i, 9) + else: + display.set_pixel(column, i, 0) + + +while True: + # detect a change in button A's state, the Mode button + button_a_state = button_a.is_pressed() + if button_a_state != last_button_a_state: + last_button_a_state = button_a_state + + #increment the mode + if button_a_state == True: + mode = (mode + 1) % 4 + display.scroll(modes[mode]) + show_time(get_clock_time()) + + # detect a change in button B's state, the increment / select button + button_b_state = button_b.is_pressed() + if button_b_state != last_button_b_state: + last_button_b_state = button_b_state + + if button_b_state == True: + # button B's action depends on the current mode + if mode == 0: #show time + display.scroll(decode_time(get_clock_time())) + elif mode == 1: #setting time: increment hour units + base_time = base_time - (60 * 60 * 1000) + elif mode == 2: #setting time: increment minute tens + base_time = base_time - (10 * 60 * 1000) + elif mode == 3: #setting time: increment minute units + base_time = base_time - (60 * 1000) + + show_time(get_clock_time()) + + + #If in clock mode update the display every second + if mode == 0: + display_time = running_time() - last_display_time + if display_time >= 1000: + last_display_time = display_time + show_time(get_clock_time()) + + sleep(100) diff --git a/examples/micropython/waveforms.py b/examples/micropython/waveforms.py new file mode 100644 index 0000000..fe3ca7c --- /dev/null +++ b/examples/micropython/waveforms.py @@ -0,0 +1,69 @@ +from microbit import display, sleep, button_a +import audio +import math + + +def repeated_frame(frame, count): + for i in range(count): + yield frame + + +# Press button A to skip to next wave. +def show_wave(name, frame, duration=1500): + display.scroll(name + " wave", wait=False, delay=100) + audio.play(repeated_frame(frame, duration), wait=False) + for i in range(75): + sleep(100) + if button_a.is_pressed(): + display.clear() + audio.stop() + break + + +frame = audio.AudioFrame() + +for i in range(len(frame)): + frame[i] = int(math.sin(math.pi * i / 16) * 124 + 128.5) +show_wave("Sine", frame) + +triangle = audio.AudioFrame() + +QUARTER = len(triangle) // 4 +for i in range(QUARTER): + triangle[i] = i * 15 + triangle[i + QUARTER] = 248 - i * 15 + triangle[i + QUARTER * 2] = 128 - i * 15 + triangle[i + QUARTER * 3] = i * 15 + 8 +show_wave("Triangle", triangle) + +square = audio.AudioFrame() + +HALF = len(square) // 2 +for i in range(HALF): + square[i] = 8 + square[i + HALF] = 248 +show_wave("Square", square) +sleep(1000) + +for i in range(len(frame)): + frame[i] = 252 - i * 8 +show_wave("Sawtooth", frame) + +del frame + +# Generate a waveform that goes from triangle to square wave, reasonably smoothly. +frames = [None] * 32 +for i in range(32): + frames[i] = frame = audio.AudioFrame() # type: ignore + for j in range(len(triangle)): + frame[j] = (triangle[j] * (32 - i) + square[j] * i) >> 5 + + +def repeated_frames(frames, count): + for frame in frames: + for i in range(count): + yield frame + + +display.scroll("Ascending wave", wait=False) +audio.play(repeated_frames(frames, 60)) # type: ignore diff --git a/introspection/api-introspection.py b/introspection/api-introspection.py new file mode 100644 index 0000000..355d598 --- /dev/null +++ b/introspection/api-introspection.py @@ -0,0 +1,118 @@ +# Script to dump symbols from a micro:bit (V2). +# The list is used to check the completeness of the type stubs. +# Largely the same as https://github.com/microbit-foundation/python-editor/blob/master/micropython/microbit-api-instropection.py + +modules = [ + # Added by Matt. We also need stubs for the u-prefixed versions noted below. + "antigravity", + "builtins", + "love", + "this", + "errno", # uerrno + "array", # uarray + "audio", + "collections", # ucollections + "gc", + "machine", + "math", + "microbit", + "micropython", + "music", + "neopixel", + "os", # oddly, no uos + "radio", + "random", # urandom + "speech", + "struct", # ustruct + "sys", # usys + "time", # utime +] + + +def nested_print(d, indent=0): + for key in sorted(d.keys()): + value = d[key] + print("{}{}".format("\t" * indent, key)) + new_inden = indent + 1 + if isinstance(value, dict): + nested_print(value, new_inden) + elif value: + print("{}{}".format("\t" * new_inden, value)) + + +def autocomplete_print(d, indent=0): + # Do we have more dicts inside? + nested_dict = False + for value in d.values(): + if value: + nested_dict = True + if not nested_dict: + # Just print as a list in a single line + print(repr(sorted(list(d.keys()))).replace("'", '"'), sep=", ", end=",\n") + else: + # At least one entry is a dictionary, so the others have value "[]" + print("{{\n".format(), end="") + for key, value in sorted(d.items()): + new_indent = indent + 1 + if isinstance(value, dict): + print('{}"{}": '.format("\t" * new_indent, key), end="") + autocomplete_print(value, new_indent) + else: + # We expect all non dictionaries to be None or falsy + print('{}"{}": "",'.format("\t" * new_indent, key)) + print("\n{}}},".format("\t" * indent)) + + +def get_api(module, module_import_str): + children = dir(module) + # print('\n{}'.format(module_import_str)) + # print('\t{}'.format(module)) + # print('\t{}'.format(children)) + api_dict = {} + for child_str in children: + # print(gc.mem_free()) + import gc + + gc.collect() + full_import_str = "{}.{}".format(module_import_str, child_str) + child = eval(full_import_str) + # Ignore all dunder methods and attributes + if child_str.startswith("_"): + pass + # Avoid infinite loops if child is parent or an instance of the parent + elif repr(module).startswith("", "") + or isinstance(child, list) + or isinstance(child, tuple) + or isinstance(child, str) + or isinstance(child, int) + ): + api_dict[child_str] = None + else: + # Anything else (classes, modules) has children for introspection + gc.collect() + api_dict[child_str] = get_api(child, full_import_str) + gc.collect() + return api_dict + + +def main(): + # We have more memory in V2 so we'll store all the API dictionary in memory + # and print in multiple formats + op = {} + for module_name in modules: + exec("import {}".format(module_name)) + op[module_name] = get_api(eval(module_name), module_name) + exec("del {}".format(module_name)) + import gc + + gc.collect() + # nested_print(op) + + +main() diff --git a/introspection/introspection.txt b/introspection/introspection.txt new file mode 100644 index 0000000..cb84bb9 --- /dev/null +++ b/introspection/introspection.txt @@ -0,0 +1,871 @@ +antigravity +array + array + append + decode + extend +audio + AudioFrame + copyfrom + is_playing + play + stop +builtins + ArithmeticError + AssertionError + AttributeError + BaseException + EOFError + Ellipsis + Exception + GeneratorExit + ImportError + IndentationError + IndexError + KeyError + KeyboardInterrupt + LookupError + MemoryError + NameError + NotImplementedError + OSError + OverflowError + RuntimeError + StopAsyncIteration + StopIteration + SyntaxError + SystemExit + TypeError + ValueError + ZeroDivisionError + abs + all + any + bin + bool + bytearray + append + decode + extend + bytes + count + decode + encode + endswith + find + format + index + isalpha + isdigit + islower + isspace + isupper + join + lower + lstrip + replace + rfind + rindex + rsplit + rstrip + split + startswith + strip + upper + callable + chr + classmethod + complex + delattr + dict + clear + copy + fromkeys + get + items + keys + pop + popitem + setdefault + update + values + dir + divmod + enumerate + eval + exec + filter + float + getattr + globals + hasattr + hash + help + hex + id + input + int + from_bytes + to_bytes + isinstance + issubclass + iter + len + list + append + clear + copy + count + extend + index + insert + pop + remove + reverse + sort + locals + map + max + memoryview + min + next + object + oct + open + ord + pow + print + property + deleter + getter + setter + range + repr + reversed + round + set + add + clear + copy + difference + difference_update + discard + intersection + intersection_update + isdisjoint + issubset + issuperset + pop + remove + symmetric_difference + symmetric_difference_update + union + update + setattr + slice + sorted + staticmethod + str + count + decode + encode + endswith + find + format + index + isalpha + isdigit + islower + isspace + isupper + join + lower + lstrip + replace + rfind + rindex + rsplit + rstrip + split + startswith + strip + upper + sum + super + tuple + count + index + type + zip +collections + OrderedDict + clear + copy + fromkeys + get + items + keys + pop + popitem + setdefault + update + values + namedtuple +errno + EACCES + EADDRINUSE + EAGAIN + EALREADY + EBADF + ECONNABORTED + ECONNREFUSED + ECONNRESET + EEXIST + EHOSTUNREACH + EINPROGRESS + EINVAL + EIO + EISDIR + ENOBUFS + ENODEV + ENOENT + ENOMEM + ENOTCONN + EOPNOTSUPP + EPERM + ETIMEDOUT + errorcode + clear + copy + fromkeys + get + items + keys + pop + popitem + setdefault + update + values +gc + collect + disable + enable + isenabled + mem_alloc + mem_free + threshold +love + badaboom +machine + disable_irq + enable_irq + freq + mem16 + mem32 + mem8 + reset + time_pulse_us + unique_id +math + acos + asin + atan + atan2 + ceil + copysign + cos + degrees + e + exp + fabs + floor + fmod + frexp + isfinite + isinf + isnan + ldexp + log + modf + pi + pow + radians + sin + sqrt + tan + trunc +microbit + Image + ALL_ARROWS + ALL_CLOCKS + ANGRY + ARROW_E + ARROW_N + ARROW_NE + ARROW_NW + ARROW_S + ARROW_SE + ARROW_SW + ARROW_W + ASLEEP + BUTTERFLY + CHESSBOARD + CLOCK1 + CLOCK10 + CLOCK11 + CLOCK12 + CLOCK2 + CLOCK3 + CLOCK4 + CLOCK5 + CLOCK6 + CLOCK7 + CLOCK8 + CLOCK9 + CONFUSED + COW + DIAMOND + DIAMOND_SMALL + DUCK + FABULOUS + GHOST + GIRAFFE + HAPPY + HEART + HEART_SMALL + HOUSE + MEH + MUSIC_CROTCHET + MUSIC_QUAVER + MUSIC_QUAVERS + NO + PACMAN + PITCHFORK + RABBIT + ROLLERSKATE + SAD + SILLY + SKULL + SMILE + SNAKE + SQUARE + SQUARE_SMALL + STICKFIGURE + SURPRISED + SWORD + TARGET + TORTOISE + TRIANGLE + TRIANGLE_LEFT + TSHIRT + UMBRELLA + XMAS + YES + blit + copy + crop + fill + get_pixel + height + invert + set_pixel + shift_down + shift_left + shift_right + shift_up + width + Sound + GIGGLE + HAPPY + HELLO + MYSTERIOUS + SAD + SLIDE + SOARING + SPRING + TWINKLE + YAWN + SoundEvent + LOUD + QUIET + accelerometer + current_gesture + get_gestures + get_values + get_x + get_y + get_z + is_gesture + was_gesture + audio + AudioFrame + copyfrom + is_playing + play + stop + button_a + get_presses + is_pressed + was_pressed + button_b + get_presses + is_pressed + was_pressed + compass + calibrate + clear_calibration + get_field_strength + get_x + get_y + get_z + heading + is_calibrated + display + clear + get_pixel + is_on + off + on + read_light_level + scroll + set_pixel + show + i2c + init + read + scan + write + microphone + current_event + get_events + is_event + set_threshold + sound_level + was_event + panic + pin0 + CAPACITIVE + NO_PULL + PULL_DOWN + PULL_UP + RESISTIVE + get_analog_period_microseconds + get_mode + get_pull + is_touched + read_analog + read_digital + set_analog_period + set_analog_period_microseconds + set_pull + set_touch_mode + write_analog + write_digital + pin1 + CAPACITIVE + NO_PULL + PULL_DOWN + PULL_UP + RESISTIVE + get_analog_period_microseconds + get_mode + get_pull + is_touched + read_analog + read_digital + set_analog_period + set_analog_period_microseconds + set_pull + set_touch_mode + write_analog + write_digital + pin10 + NO_PULL + PULL_DOWN + PULL_UP + get_analog_period_microseconds + get_mode + get_pull + read_analog + read_digital + set_analog_period + set_analog_period_microseconds + set_pull + write_analog + write_digital + pin11 + NO_PULL + PULL_DOWN + PULL_UP + get_analog_period_microseconds + get_mode + get_pull + read_digital + set_analog_period + set_analog_period_microseconds + set_pull + write_analog + write_digital + pin12 + NO_PULL + PULL_DOWN + PULL_UP + get_analog_period_microseconds + get_mode + get_pull + read_digital + set_analog_period + set_analog_period_microseconds + set_pull + write_analog + write_digital + pin13 + NO_PULL + PULL_DOWN + PULL_UP + get_analog_period_microseconds + get_mode + get_pull + read_digital + set_analog_period + set_analog_period_microseconds + set_pull + write_analog + write_digital + pin14 + NO_PULL + PULL_DOWN + PULL_UP + get_analog_period_microseconds + get_mode + get_pull + read_digital + set_analog_period + set_analog_period_microseconds + set_pull + write_analog + write_digital + pin15 + NO_PULL + PULL_DOWN + PULL_UP + get_analog_period_microseconds + get_mode + get_pull + read_digital + set_analog_period + set_analog_period_microseconds + set_pull + write_analog + write_digital + pin16 + NO_PULL + PULL_DOWN + PULL_UP + get_analog_period_microseconds + get_mode + get_pull + read_digital + set_analog_period + set_analog_period_microseconds + set_pull + write_analog + write_digital + pin19 + NO_PULL + PULL_DOWN + PULL_UP + get_analog_period_microseconds + get_mode + get_pull + read_digital + set_analog_period + set_analog_period_microseconds + set_pull + write_analog + write_digital + pin2 + CAPACITIVE + NO_PULL + PULL_DOWN + PULL_UP + RESISTIVE + get_analog_period_microseconds + get_mode + get_pull + is_touched + read_analog + read_digital + set_analog_period + set_analog_period_microseconds + set_pull + set_touch_mode + write_analog + write_digital + pin20 + NO_PULL + PULL_DOWN + PULL_UP + get_analog_period_microseconds + get_mode + get_pull + read_digital + set_analog_period + set_analog_period_microseconds + set_pull + write_analog + write_digital + pin3 + NO_PULL + PULL_DOWN + PULL_UP + get_analog_period_microseconds + get_mode + get_pull + read_analog + read_digital + set_analog_period + set_analog_period_microseconds + set_pull + write_analog + write_digital + pin4 + NO_PULL + PULL_DOWN + PULL_UP + get_analog_period_microseconds + get_mode + get_pull + read_analog + read_digital + set_analog_period + set_analog_period_microseconds + set_pull + write_analog + write_digital + pin5 + NO_PULL + PULL_DOWN + PULL_UP + get_analog_period_microseconds + get_mode + get_pull + read_digital + set_analog_period + set_analog_period_microseconds + set_pull + write_analog + write_digital + pin6 + NO_PULL + PULL_DOWN + PULL_UP + get_analog_period_microseconds + get_mode + get_pull + read_digital + set_analog_period + set_analog_period_microseconds + set_pull + write_analog + write_digital + pin7 + NO_PULL + PULL_DOWN + PULL_UP + get_analog_period_microseconds + get_mode + get_pull + read_digital + set_analog_period + set_analog_period_microseconds + set_pull + write_analog + write_digital + pin8 + NO_PULL + PULL_DOWN + PULL_UP + get_analog_period_microseconds + get_mode + get_pull + read_digital + set_analog_period + set_analog_period_microseconds + set_pull + write_analog + write_digital + pin9 + NO_PULL + PULL_DOWN + PULL_UP + get_analog_period_microseconds + get_mode + get_pull + read_digital + set_analog_period + set_analog_period_microseconds + set_pull + write_analog + write_digital + pin_logo + CAPACITIVE + RESISTIVE + is_touched + set_touch_mode + pin_speaker + NO_PULL + PULL_DOWN + PULL_UP + get_analog_period_microseconds + get_mode + get_pull + read_digital + set_analog_period + set_analog_period_microseconds + set_pull + write_analog + write_digital + reset + running_time + set_volume + sleep + speaker + off + on + spi + init + read + write + write_readinto + temperature + uart + EVEN + ODD + any + init + read + readinto + readline + write + ws2812_write +micropython + const + heap_lock + heap_unlock + kbd_intr + mem_info + opt_level + qstr_info + schedule + stack_use +music + BADDY + BA_DING + BIRTHDAY + BLUES + CHASE + DADADADUM + ENTERTAINER + FUNERAL + FUNK + JUMP_DOWN + JUMP_UP + NYAN + ODE + POWER_DOWN + POWER_UP + PRELUDE + PUNCHLINE + PYTHON + RINGTONE + WAWAWAWAA + WEDDING + get_tempo + pitch + play + reset + set_tempo + stop +neopixel + NeoPixel + ORDER + clear + fill + show + write + ws2812_write +os + ilistdir + listdir + remove + size + stat + uname +radio + RATE_1MBIT + RATE_2MBIT + config + off + on + receive + receive_bytes + receive_bytes_into + receive_full + reset + send + send_bytes +random + choice + getrandbits + randint + random + randrange + seed + uniform +speech + pronounce + say + sing + translate +struct + calcsize + pack + pack_into + unpack + unpack_from +sys + argv + byteorder + exit + implementation + name + version + maxsize + modules + clear + copy + fromkeys + get + items + keys + pop + popitem + setdefault + update + values + path + platform + print_exception + version + version_info +this + authors +time + sleep + sleep_ms + sleep_us + ticks_add + ticks_diff + ticks_ms + ticks_us diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..3e09610 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,13 @@ +{ + "name": "micropython-microbit-stubs", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "pyright": { + "version": "1.1.166", + "resolved": "https://registry.npmjs.org/pyright/-/pyright-1.1.166.tgz", + "integrity": "sha512-mO+iPT2dhHzlplAV3iKE6u4gUstGZxxLyMSRd1PKZqWhwhTCCGjn3/7VqbAwUt4fuhY8g0V+SAsu+MPT4H3FvQ==" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..9ce6267 --- /dev/null +++ b/package.json @@ -0,0 +1,21 @@ +{ + "name": "micropython-microbit-stubs", + "version": "1.0.0", + "description": "Temporary home for micro:bit MicroPython stubs.", + "scripts": { + "test": "pyright -p test-pyrightconfig.json" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/microbit-foundation/micropython-microbit-stubs.git" + }, + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/microbit-foundation/micropython-microbit-stubs/issues" + }, + "homepage": "https://github.com/microbit-foundation/micropython-microbit-stubs#readme", + "dependencies": { + "pyright": "^1.1.166" + } +} diff --git a/test-pyrightconfig.json b/test-pyrightconfig.json new file mode 100644 index 0000000..f87bb64 --- /dev/null +++ b/test-pyrightconfig.json @@ -0,0 +1,14 @@ +{ + "include": ["./examples"], + "pythonVersion": "3.6", + "pythonPlatform": "Linux", + "typeCheckingMode": "basic", + "typeshedPath": "./typeshed/", + "reportMissingModuleSource": false, + "reportWildcardImportFromLibrary": false, + "reportInvalidStubStatement": true, + "reportIncompleteStub": true, + "reportMissingTypeStubs": true, + + "verboseOutput": true + } diff --git a/typeshed/stdlib/VERSIONS b/typeshed/stdlib/VERSIONS new file mode 100644 index 0000000..67b710f --- /dev/null +++ b/typeshed/stdlib/VERSIONS @@ -0,0 +1,50 @@ +# The structure of this file is as follows: +# - Blank lines and comments starting with `#` are ignored. +# - Lines contain the name of a module, followed by a colon, +# a space, and a version range (for example: `symbol: 2.7-3.9`). +# +# Version ranges may be of the form "X.Y-A.B" or "X.Y-". The +# first form means that a module was introduced in version X.Y and last +# available in version A.B. The second form means that the module was +# introduced in version X.Y and is still available in the latest +# version of Python. +# +# If a submodule is not listed separately, it has the same lifetime as +# its parent module. +# +# Python versions before 2.7 are ignored, so any module that was already +# present in 2.7 will have "2.7" as its minimum version. Version ranges +# for unsupported versions of Python 3 (currently 3.5 and lower) are +# generally accurate but we do not guarantee their correctness. + +antigravity: 3.0- +array: 3.0- +audio: 3.0- +builtins: 3.0- +errno: 3.0- +gc: 3.0- +love: 3.0- +machine: 3.0- +math: 3.0- +microbit: 3.0- +micropython: 3.0- +music: 3.0- +neopixel: 3.0- +os: 3.0- +radio: 3.0- +random: 3.0- +speech: 3.0- +struct: 3.0- +sys: 3.0- +this: 3.0- +time: 3.0- +typing_extensions: 3.0- +typing: 3.0- +uarray: 3.0- +ucollections: 3.0- +uerrno: 3.0- +uos: 3.0- +urandom: 3.0- +ustruct: 3.0- +usys: 3.0- +utime: 3.0- \ No newline at end of file diff --git a/typeshed/stdlib/_typeshed/__init__.pyi b/typeshed/stdlib/_typeshed/__init__.pyi new file mode 100644 index 0000000..7bf6e72 --- /dev/null +++ b/typeshed/stdlib/_typeshed/__init__.pyi @@ -0,0 +1,168 @@ +# Utility types for typeshed +# +# See the README.md file in this directory for more information. + +import array +import sys +from os import PathLike +from typing import AbstractSet, Any, Container, Iterable, Protocol, Tuple, TypeVar, Union +from typing_extensions import Literal, final + +_KT = TypeVar("_KT") +_KT_co = TypeVar("_KT_co", covariant=True) +_KT_contra = TypeVar("_KT_contra", contravariant=True) +_VT = TypeVar("_VT") +_VT_co = TypeVar("_VT_co", covariant=True) +_T = TypeVar("_T") +_T_co = TypeVar("_T_co", covariant=True) +_T_contra = TypeVar("_T_contra", contravariant=True) + +# Use for "self" annotations: +# def __enter__(self: Self) -> Self: ... +Self = TypeVar("Self") # noqa Y001 + +# stable +class IdentityFunction(Protocol): + def __call__(self, __x: _T) -> _T: ... + +class SupportsLessThan(Protocol): + def __lt__(self, __other: Any) -> bool: ... + +SupportsLessThanT = TypeVar("SupportsLessThanT", bound=SupportsLessThan) # noqa: Y001 + +class SupportsDivMod(Protocol[_T_contra, _T_co]): + def __divmod__(self, __other: _T_contra) -> _T_co: ... + +class SupportsRDivMod(Protocol[_T_contra, _T_co]): + def __rdivmod__(self, __other: _T_contra) -> _T_co: ... + +class SupportsLenAndGetItem(Protocol[_T_co]): + def __len__(self) -> int: ... + def __getitem__(self, __k: int) -> _T_co: ... + +# Mapping-like protocols + +# stable +class SupportsItems(Protocol[_KT_co, _VT_co]): + def items(self) -> AbstractSet[Tuple[_KT_co, _VT_co]]: ... + +# stable +class SupportsKeysAndGetItem(Protocol[_KT, _VT_co]): + def keys(self) -> Iterable[_KT]: ... + def __getitem__(self, __k: _KT) -> _VT_co: ... + +# stable +class SupportsGetItem(Container[_KT_contra], Protocol[_KT_contra, _VT_co]): + def __getitem__(self, __k: _KT_contra) -> _VT_co: ... + +# stable +class SupportsItemAccess(SupportsGetItem[_KT_contra, _VT], Protocol[_KT_contra, _VT]): + def __setitem__(self, __k: _KT_contra, __v: _VT) -> None: ... + def __delitem__(self, __v: _KT_contra) -> None: ... + +# These aliases are simple strings in Python 2. +StrPath = Union[str, PathLike[str]] # stable +BytesPath = Union[bytes, PathLike[bytes]] # stable +StrOrBytesPath = Union[str, bytes, PathLike[str], PathLike[bytes]] # stable + +OpenTextModeUpdating = Literal[ + "r+", + "+r", + "rt+", + "r+t", + "+rt", + "tr+", + "t+r", + "+tr", + "w+", + "+w", + "wt+", + "w+t", + "+wt", + "tw+", + "t+w", + "+tw", + "a+", + "+a", + "at+", + "a+t", + "+at", + "ta+", + "t+a", + "+ta", + "x+", + "+x", + "xt+", + "x+t", + "+xt", + "tx+", + "t+x", + "+tx", +] +OpenTextModeWriting = Literal["w", "wt", "tw", "a", "at", "ta", "x", "xt", "tx"] +OpenTextModeReading = Literal["r", "rt", "tr", "U", "rU", "Ur", "rtU", "rUt", "Urt", "trU", "tUr", "Utr"] +OpenTextMode = Union[OpenTextModeUpdating, OpenTextModeWriting, OpenTextModeReading] +OpenBinaryModeUpdating = Literal[ + "rb+", + "r+b", + "+rb", + "br+", + "b+r", + "+br", + "wb+", + "w+b", + "+wb", + "bw+", + "b+w", + "+bw", + "ab+", + "a+b", + "+ab", + "ba+", + "b+a", + "+ba", + "xb+", + "x+b", + "+xb", + "bx+", + "b+x", + "+bx", +] +OpenBinaryModeWriting = Literal["wb", "bw", "ab", "ba", "xb", "bx"] +OpenBinaryModeReading = Literal["rb", "br", "rbU", "rUb", "Urb", "brU", "bUr", "Ubr"] +OpenBinaryMode = Union[OpenBinaryModeUpdating, OpenBinaryModeReading, OpenBinaryModeWriting] + +# stable +class HasFileno(Protocol): + def fileno(self) -> int: ... + +FileDescriptor = int # stable +FileDescriptorLike = Union[int, HasFileno] # stable + +# stable +class SupportsRead(Protocol[_T_co]): + def read(self, __length: int = ...) -> _T_co: ... + +# stable +class SupportsReadline(Protocol[_T_co]): + def readline(self, __length: int = ...) -> _T_co: ... + +# stable +class SupportsNoArgReadline(Protocol[_T_co]): + def readline(self) -> _T_co: ... + +# stable +class SupportsWrite(Protocol[_T_contra]): + def write(self, __s: _T_contra) -> Any: ... + +ReadableBuffer = Union[bytes, bytearray, memoryview, array.array[Any]] # stable +WriteableBuffer = Union[bytearray, memoryview, array.array[Any]] # stable + +# stable +if sys.version_info >= (3, 10): + from types import NoneType as NoneType +else: + # Used by type checkers for checks involving None (does not exist at runtime) + @final + class NoneType: + def __bool__(self) -> Literal[False]: ... diff --git a/typeshed/stdlib/antigravity.pyi b/typeshed/stdlib/antigravity.pyi new file mode 100644 index 0000000..e69de29 diff --git a/typeshed/stdlib/array.pyi b/typeshed/stdlib/array.pyi new file mode 100644 index 0000000..7a5e9ca --- /dev/null +++ b/typeshed/stdlib/array.pyi @@ -0,0 +1 @@ +from uarray import * diff --git a/typeshed/stdlib/audio.pyi b/typeshed/stdlib/audio.pyi new file mode 100644 index 0000000..04708d3 --- /dev/null +++ b/typeshed/stdlib/audio.pyi @@ -0,0 +1,55 @@ +"""This module allows you to play your own sounds. If you are using a micro:bit +**V2**, ``audio`` is also part of the ``microbit`` module. + +By default sound output will be via the edge connector on pin 0 and the +:doc:`built-in speaker ` **V2**. You can connect wired headphones or +a speaker to pin 0 and GND on the edge connector to hear the sounds. +""" + +from .microbit import MicroBitDigitalPin, Sound +from typing import Iterable, Union + +def play( + source: Union[Iterable[AudioFrame], Sound], + wait: bool = True, + pin: MicroBitDigitalPin = ..., + return_pin: MicroBitDigitalPin = ..., +) -> None: + """Play the source to completion. + + * **source**: ``Sound`` - The ``microbit`` module contains a list of + built-in sounds that your can pass to ``audio.play()``. + + * **source**: ``AudioFrame`` - The source agrument can also be an iterable + of ``AudioFrame`` elements as described below. + + * **wait**: If ``wait`` is ``True``, this function will block until the + source is exhausted. + + * **pin**: An optional argument to specify the output pin can be used to + override the default of ``pin0``. If we do not want any sound to play + we can use ``pin=None``. + + * **return_pin**: specifies a differential edge connector pin to connect + to an external speaker instead of ground. This is ignored for the **V2** + revision. + """ + +def is_playing() -> bool: + """Return ``True`` if audio is playing, otherwise return ``False``.""" + ... + +def stop() -> None: + """Stops all audio playback.""" + ... + +class AudioFrame: + """An ``AudioFrame`` object is a list of 32 samples each of which is a signed byte + (whole number between -128 and 127). + + It takes just over 4 ms to play a single frame. + """ + + def __len__(self) -> int: ... + def __setitem__(self, key: int, value: int) -> None: ... + def __getitem__(self, key: int) -> int: ... diff --git a/typeshed/stdlib/builtins.pyi b/typeshed/stdlib/builtins.pyi new file mode 100644 index 0000000..1e95598 --- /dev/null +++ b/typeshed/stdlib/builtins.pyi @@ -0,0 +1,1511 @@ +import sys +import types +from _typeshed import ( + OpenBinaryMode, + OpenBinaryModeReading, + OpenBinaryModeUpdating, + OpenBinaryModeWriting, + OpenTextMode, + ReadableBuffer, + Self, + StrOrBytesPath, + SupportsDivMod, + SupportsKeysAndGetItem, + SupportsLessThan, + SupportsLessThanT, + SupportsRDivMod, + SupportsWrite, +) +from types import CodeType, TracebackType +from typing import ( + IO, + AbstractSet, + Any, + AsyncIterable, + AsyncIterator, + BinaryIO, + ByteString, + Callable, + Dict, + FrozenSet, + Generic, + ItemsView, + Iterable, + Iterator, + KeysView, + List, + Mapping, + MutableMapping, + MutableSequence, + MutableSet, + NoReturn, + Optional, + Protocol, + Reversible, + Sequence, + Set, + Sized, + SupportsAbs, + SupportsBytes, + SupportsComplex, + SupportsFloat, + SupportsInt, + SupportsRound, + Tuple, + Type, + TypeVar, + Union, + ValuesView, + overload, +) +from typing_extensions import Literal, SupportsIndex, final + +if sys.version_info >= (3, 9): + from types import GenericAlias + +class _SupportsTrunc(Protocol): + def __trunc__(self) -> int: ... + +_T = TypeVar("_T") +_T_co = TypeVar("_T_co", covariant=True) +_T_contra = TypeVar("_T_contra", contravariant=True) +_KT = TypeVar("_KT") +_VT = TypeVar("_VT") +_S = TypeVar("_S") +_T1 = TypeVar("_T1") +_T2 = TypeVar("_T2") +_T3 = TypeVar("_T3") +_T4 = TypeVar("_T4") +_T5 = TypeVar("_T5") +_TT = TypeVar("_TT", bound="type") +_TBE = TypeVar("_TBE", bound="BaseException") + +class object: + __doc__: Optional[str] + __dict__: Dict[str, Any] + __slots__: Union[str, Iterable[str]] + __module__: str + __annotations__: Dict[str, Any] + @property + def __class__(self: _T) -> Type[_T]: ... + # Ignore errors about type mismatch between property getter and setter + @__class__.setter + def __class__(self, __type: Type[object]) -> None: ... # type: ignore # noqa: F811 + def __init__(self) -> None: ... + def __new__(cls) -> Any: ... + def __setattr__(self, name: str, value: Any) -> None: ... + def __eq__(self, o: object) -> bool: ... + def __ne__(self, o: object) -> bool: ... + def __str__(self) -> str: ... + def __repr__(self) -> str: ... + def __hash__(self) -> int: ... + def __format__(self, format_spec: str) -> str: ... + def __getattribute__(self, name: str) -> Any: ... + def __delattr__(self, name: str) -> None: ... + def __sizeof__(self) -> int: ... + def __reduce__(self) -> Union[str, Tuple[Any, ...]]: ... + if sys.version_info >= (3, 8): + def __reduce_ex__(self, protocol: SupportsIndex) -> str | Tuple[Any, ...]: ... + else: + def __reduce_ex__(self, protocol: int) -> str | Tuple[Any, ...]: ... + def __dir__(self) -> Iterable[str]: ... + def __init_subclass__(cls) -> None: ... + +class staticmethod(object): # Special, only valid as a decorator. + __func__: Callable[..., Any] + __isabstractmethod__: bool + def __init__(self, f: Callable[..., Any]) -> None: ... + def __new__(cls: Type[_T], *args: Any, **kwargs: Any) -> _T: ... + def __get__(self, obj: _T, type: Optional[Type[_T]] = ...) -> Callable[..., Any]: ... + +class classmethod(object): # Special, only valid as a decorator. + __func__: Callable[..., Any] + __isabstractmethod__: bool + def __init__(self, f: Callable[..., Any]) -> None: ... + def __new__(cls: Type[_T], *args: Any, **kwargs: Any) -> _T: ... + def __get__(self, obj: _T, type: Optional[Type[_T]] = ...) -> Callable[..., Any]: ... + +class type(object): + __base__: type + __bases__: Tuple[type, ...] + __basicsize__: int + __dict__: Dict[str, Any] + __dictoffset__: int + __flags__: int + __itemsize__: int + __module__: str + __mro__: Tuple[type, ...] + __name__: str + __qualname__: str + __text_signature__: Optional[str] + __weakrefoffset__: int + @overload + def __init__(self, o: object) -> None: ... + @overload + def __init__(self, name: str, bases: Tuple[type, ...], dict: Dict[str, Any], **kwds: Any) -> None: ... + @overload + def __new__(cls, o: object) -> type: ... + @overload + def __new__(cls: Type[_TT], name: str, bases: Tuple[type, ...], namespace: Dict[str, Any], **kwds: Any) -> _TT: ... + def __call__(self, *args: Any, **kwds: Any) -> Any: ... + def __subclasses__(self: _TT) -> List[_TT]: ... + # Note: the documentation doesnt specify what the return type is, the standard + # implementation seems to be returning a list. + def mro(self) -> List[type]: ... + def __instancecheck__(self, instance: Any) -> bool: ... + def __subclasscheck__(self, subclass: type) -> bool: ... + @classmethod + def __prepare__(metacls, __name: str, __bases: Tuple[type, ...], **kwds: Any) -> Mapping[str, Any]: ... + if sys.version_info >= (3, 10): + def __or__(self, t: Any) -> types.Union: ... + def __ror__(self, t: Any) -> types.Union: ... + +class super(object): + @overload + def __init__(self, t: Any, obj: Any) -> None: ... + @overload + def __init__(self, t: Any) -> None: ... + @overload + def __init__(self) -> None: ... + +class int: + @overload + def __new__(cls: Type[_T], x: Union[str, bytes, SupportsInt, SupportsIndex, _SupportsTrunc] = ...) -> _T: ... + @overload + def __new__(cls: Type[_T], x: Union[str, bytes, bytearray], base: SupportsIndex) -> _T: ... + if sys.version_info >= (3, 8): + def as_integer_ratio(self) -> Tuple[int, Literal[1]]: ... + @property + def real(self) -> int: ... + @property + def imag(self) -> int: ... + @property + def numerator(self) -> int: ... + @property + def denominator(self) -> int: ... + def conjugate(self) -> int: ... + def bit_length(self) -> int: ... + if sys.version_info >= (3, 10): + def bit_count(self) -> int: ... + def to_bytes(self, length: SupportsIndex, byteorder: Literal["little", "big"], *, signed: bool = ...) -> bytes: ... + @classmethod + def from_bytes( + cls, bytes: Iterable[SupportsIndex] | SupportsBytes, byteorder: Literal["little", "big"], *, signed: bool = ... + ) -> int: ... # TODO buffer object argument + def __add__(self, x: int) -> int: ... + def __sub__(self, x: int) -> int: ... + def __mul__(self, x: int) -> int: ... + def __floordiv__(self, x: int) -> int: ... + def __truediv__(self, x: int) -> float: ... + def __mod__(self, x: int) -> int: ... + def __divmod__(self, x: int) -> Tuple[int, int]: ... + def __radd__(self, x: int) -> int: ... + def __rsub__(self, x: int) -> int: ... + def __rmul__(self, x: int) -> int: ... + def __rfloordiv__(self, x: int) -> int: ... + def __rtruediv__(self, x: int) -> float: ... + def __rmod__(self, x: int) -> int: ... + def __rdivmod__(self, x: int) -> Tuple[int, int]: ... + @overload + def __pow__(self, __x: Literal[2], __modulo: Optional[int] = ...) -> int: ... + @overload + def __pow__(self, __x: int, __modulo: Optional[int] = ...) -> Any: ... # Return type can be int or float, depending on x. + def __rpow__(self, x: int, mod: Optional[int] = ...) -> Any: ... + def __and__(self, n: int) -> int: ... + def __or__(self, n: int) -> int: ... + def __xor__(self, n: int) -> int: ... + def __lshift__(self, n: int) -> int: ... + def __rshift__(self, n: int) -> int: ... + def __rand__(self, n: int) -> int: ... + def __ror__(self, n: int) -> int: ... + def __rxor__(self, n: int) -> int: ... + def __rlshift__(self, n: int) -> int: ... + def __rrshift__(self, n: int) -> int: ... + def __neg__(self) -> int: ... + def __pos__(self) -> int: ... + def __invert__(self) -> int: ... + def __trunc__(self) -> int: ... + def __ceil__(self) -> int: ... + def __floor__(self) -> int: ... + def __round__(self, ndigits: SupportsIndex = ...) -> int: ... + def __getnewargs__(self) -> Tuple[int]: ... + def __eq__(self, x: object) -> bool: ... + def __ne__(self, x: object) -> bool: ... + def __lt__(self, x: int) -> bool: ... + def __le__(self, x: int) -> bool: ... + def __gt__(self, x: int) -> bool: ... + def __ge__(self, x: int) -> bool: ... + def __str__(self) -> str: ... + def __float__(self) -> float: ... + def __int__(self) -> int: ... + def __abs__(self) -> int: ... + def __hash__(self) -> int: ... + def __bool__(self) -> bool: ... + def __index__(self) -> int: ... + +class float: + def __new__(cls: Type[_T], x: Union[SupportsFloat, SupportsIndex, str, bytes, bytearray] = ...) -> _T: ... + def as_integer_ratio(self) -> Tuple[int, int]: ... + def hex(self) -> str: ... + def is_integer(self) -> bool: ... + @classmethod + def fromhex(cls, __s: str) -> float: ... + @property + def real(self) -> float: ... + @property + def imag(self) -> float: ... + def conjugate(self) -> float: ... + def __add__(self, x: float) -> float: ... + def __sub__(self, x: float) -> float: ... + def __mul__(self, x: float) -> float: ... + def __floordiv__(self, x: float) -> float: ... + def __truediv__(self, x: float) -> float: ... + def __mod__(self, x: float) -> float: ... + def __divmod__(self, x: float) -> Tuple[float, float]: ... + def __pow__( + self, x: float, mod: None = ... + ) -> float: ... # In Python 3, returns complex if self is negative and x is not whole + def __radd__(self, x: float) -> float: ... + def __rsub__(self, x: float) -> float: ... + def __rmul__(self, x: float) -> float: ... + def __rfloordiv__(self, x: float) -> float: ... + def __rtruediv__(self, x: float) -> float: ... + def __rmod__(self, x: float) -> float: ... + def __rdivmod__(self, x: float) -> Tuple[float, float]: ... + def __rpow__(self, x: float, mod: None = ...) -> float: ... + def __getnewargs__(self) -> Tuple[float]: ... + def __trunc__(self) -> int: ... + if sys.version_info >= (3, 9): + def __ceil__(self) -> int: ... + def __floor__(self) -> int: ... + @overload + def __round__(self, ndigits: None = ...) -> int: ... + @overload + def __round__(self, ndigits: SupportsIndex) -> float: ... + def __eq__(self, x: object) -> bool: ... + def __ne__(self, x: object) -> bool: ... + def __lt__(self, x: float) -> bool: ... + def __le__(self, x: float) -> bool: ... + def __gt__(self, x: float) -> bool: ... + def __ge__(self, x: float) -> bool: ... + def __neg__(self) -> float: ... + def __pos__(self) -> float: ... + def __str__(self) -> str: ... + def __int__(self) -> int: ... + def __float__(self) -> float: ... + def __abs__(self) -> float: ... + def __hash__(self) -> int: ... + def __bool__(self) -> bool: ... + +class complex: + @overload + def __new__(cls: Type[_T], real: float = ..., imag: float = ...) -> _T: ... + @overload + def __new__(cls: Type[_T], real: Union[str, SupportsComplex, SupportsIndex, complex]) -> _T: ... + @property + def real(self) -> float: ... + @property + def imag(self) -> float: ... + def conjugate(self) -> complex: ... + def __add__(self, x: complex) -> complex: ... + def __sub__(self, x: complex) -> complex: ... + def __mul__(self, x: complex) -> complex: ... + def __pow__(self, x: complex, mod: None = ...) -> complex: ... + def __truediv__(self, x: complex) -> complex: ... + def __radd__(self, x: complex) -> complex: ... + def __rsub__(self, x: complex) -> complex: ... + def __rmul__(self, x: complex) -> complex: ... + def __rpow__(self, x: complex, mod: None = ...) -> complex: ... + def __rtruediv__(self, x: complex) -> complex: ... + def __eq__(self, x: object) -> bool: ... + def __ne__(self, x: object) -> bool: ... + def __neg__(self) -> complex: ... + def __pos__(self) -> complex: ... + def __str__(self) -> str: ... + def __abs__(self) -> float: ... + def __hash__(self) -> int: ... + def __bool__(self) -> bool: ... + +class _FormatMapMapping(Protocol): + def __getitem__(self, __key: str) -> Any: ... + +class str(Sequence[str]): + @overload + def __new__(cls: Type[_T], o: object = ...) -> _T: ... + @overload + def __new__(cls: Type[_T], o: bytes, encoding: str = ..., errors: str = ...) -> _T: ... + def capitalize(self) -> str: ... + def casefold(self) -> str: ... + def center(self, __width: SupportsIndex, __fillchar: str = ...) -> str: ... + def count(self, x: str, __start: Optional[SupportsIndex] = ..., __end: Optional[SupportsIndex] = ...) -> int: ... + def encode(self, encoding: str = ..., errors: str = ...) -> bytes: ... + def endswith( + self, __suffix: Union[str, Tuple[str, ...]], __start: Optional[SupportsIndex] = ..., __end: Optional[SupportsIndex] = ... + ) -> bool: ... + if sys.version_info >= (3, 8): + def expandtabs(self, tabsize: SupportsIndex = ...) -> str: ... + else: + def expandtabs(self, tabsize: int = ...) -> str: ... + def find(self, __sub: str, __start: Optional[SupportsIndex] = ..., __end: Optional[SupportsIndex] = ...) -> int: ... + def format(self, *args: object, **kwargs: object) -> str: ... + def format_map(self, map: _FormatMapMapping) -> str: ... + def index(self, __sub: str, __start: Optional[SupportsIndex] = ..., __end: Optional[SupportsIndex] = ...) -> int: ... + def isalnum(self) -> bool: ... + def isalpha(self) -> bool: ... + if sys.version_info >= (3, 7): + def isascii(self) -> bool: ... + def isdecimal(self) -> bool: ... + def isdigit(self) -> bool: ... + def isidentifier(self) -> bool: ... + def islower(self) -> bool: ... + def isnumeric(self) -> bool: ... + def isprintable(self) -> bool: ... + def isspace(self) -> bool: ... + def istitle(self) -> bool: ... + def isupper(self) -> bool: ... + def join(self, __iterable: Iterable[str]) -> str: ... + def ljust(self, __width: SupportsIndex, __fillchar: str = ...) -> str: ... + def lower(self) -> str: ... + def lstrip(self, __chars: Optional[str] = ...) -> str: ... + def partition(self, __sep: str) -> Tuple[str, str, str]: ... + def replace(self, __old: str, __new: str, __count: SupportsIndex = ...) -> str: ... + if sys.version_info >= (3, 9): + def removeprefix(self, __prefix: str) -> str: ... + def removesuffix(self, __suffix: str) -> str: ... + def rfind(self, __sub: str, __start: Optional[SupportsIndex] = ..., __end: Optional[SupportsIndex] = ...) -> int: ... + def rindex(self, __sub: str, __start: Optional[SupportsIndex] = ..., __end: Optional[SupportsIndex] = ...) -> int: ... + def rjust(self, __width: SupportsIndex, __fillchar: str = ...) -> str: ... + def rpartition(self, __sep: str) -> Tuple[str, str, str]: ... + def rsplit(self, sep: Optional[str] = ..., maxsplit: SupportsIndex = ...) -> List[str]: ... + def rstrip(self, __chars: Optional[str] = ...) -> str: ... + def split(self, sep: Optional[str] = ..., maxsplit: SupportsIndex = ...) -> List[str]: ... + def splitlines(self, keepends: bool = ...) -> List[str]: ... + def startswith( + self, __prefix: Union[str, Tuple[str, ...]], __start: Optional[SupportsIndex] = ..., __end: Optional[SupportsIndex] = ... + ) -> bool: ... + def strip(self, __chars: Optional[str] = ...) -> str: ... + def swapcase(self) -> str: ... + def title(self) -> str: ... + def translate(self, __table: Union[Mapping[int, Union[int, str, None]], Sequence[Union[int, str, None]]]) -> str: ... + def upper(self) -> str: ... + def zfill(self, __width: SupportsIndex) -> str: ... + @staticmethod + @overload + def maketrans(__x: Union[Dict[int, _T], Dict[str, _T], Dict[Union[str, int], _T]]) -> Dict[int, _T]: ... + @staticmethod + @overload + def maketrans(__x: str, __y: str, __z: Optional[str] = ...) -> Dict[int, Union[int, None]]: ... + def __add__(self, s: str) -> str: ... + # Incompatible with Sequence.__contains__ + def __contains__(self, o: str) -> bool: ... # type: ignore + def __eq__(self, x: object) -> bool: ... + def __ge__(self, x: str) -> bool: ... + def __getitem__(self, i: Union[int, slice]) -> str: ... + def __gt__(self, x: str) -> bool: ... + def __hash__(self) -> int: ... + def __iter__(self) -> Iterator[str]: ... + def __le__(self, x: str) -> bool: ... + def __len__(self) -> int: ... + def __lt__(self, x: str) -> bool: ... + def __mod__(self, x: Any) -> str: ... + def __mul__(self, n: SupportsIndex) -> str: ... + def __ne__(self, x: object) -> bool: ... + def __repr__(self) -> str: ... + def __rmul__(self, n: SupportsIndex) -> str: ... + def __str__(self) -> str: ... + def __getnewargs__(self) -> Tuple[str]: ... + +class bytes(ByteString): + @overload + def __new__(cls: Type[_T], ints: Iterable[SupportsIndex]) -> _T: ... + @overload + def __new__(cls: Type[_T], string: str, encoding: str, errors: str = ...) -> _T: ... + @overload + def __new__(cls: Type[_T], length: SupportsIndex) -> _T: ... + @overload + def __new__(cls: Type[_T]) -> _T: ... + @overload + def __new__(cls: Type[_T], o: SupportsBytes) -> _T: ... + def capitalize(self) -> bytes: ... + def center(self, __width: SupportsIndex, __fillchar: bytes = ...) -> bytes: ... + def count( + self, __sub: bytes | SupportsIndex, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... + ) -> int: ... + def decode(self, encoding: str = ..., errors: str = ...) -> str: ... + def endswith( + self, + __suffix: Union[bytes, Tuple[bytes, ...]], + __start: Optional[SupportsIndex] = ..., + __end: Optional[SupportsIndex] = ..., + ) -> bool: ... + if sys.version_info >= (3, 8): + def expandtabs(self, tabsize: SupportsIndex = ...) -> bytes: ... + else: + def expandtabs(self, tabsize: int = ...) -> bytes: ... + def find( + self, __sub: bytes | SupportsIndex, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... + ) -> int: ... + if sys.version_info >= (3, 8): + def hex(self, sep: Union[str, bytes] = ..., bytes_per_sep: SupportsIndex = ...) -> str: ... + else: + def hex(self) -> str: ... + def index( + self, __sub: bytes | SupportsIndex, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... + ) -> int: ... + def isalnum(self) -> bool: ... + def isalpha(self) -> bool: ... + if sys.version_info >= (3, 7): + def isascii(self) -> bool: ... + def isdigit(self) -> bool: ... + def islower(self) -> bool: ... + def isspace(self) -> bool: ... + def istitle(self) -> bool: ... + def isupper(self) -> bool: ... + def join(self, __iterable_of_bytes: Iterable[Union[ByteString, memoryview]]) -> bytes: ... + def ljust(self, __width: SupportsIndex, __fillchar: bytes = ...) -> bytes: ... + def lower(self) -> bytes: ... + def lstrip(self, __bytes: Optional[bytes] = ...) -> bytes: ... + def partition(self, __sep: bytes) -> Tuple[bytes, bytes, bytes]: ... + def replace(self, __old: bytes, __new: bytes, __count: SupportsIndex = ...) -> bytes: ... + if sys.version_info >= (3, 9): + def removeprefix(self, __prefix: bytes) -> bytes: ... + def removesuffix(self, __suffix: bytes) -> bytes: ... + def rfind( + self, __sub: bytes | SupportsIndex, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... + ) -> int: ... + def rindex( + self, __sub: bytes | SupportsIndex, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... + ) -> int: ... + def rjust(self, __width: SupportsIndex, __fillchar: bytes = ...) -> bytes: ... + def rpartition(self, __sep: bytes) -> Tuple[bytes, bytes, bytes]: ... + def rsplit(self, sep: Optional[bytes] = ..., maxsplit: SupportsIndex = ...) -> List[bytes]: ... + def rstrip(self, __bytes: Optional[bytes] = ...) -> bytes: ... + def split(self, sep: Optional[bytes] = ..., maxsplit: SupportsIndex = ...) -> List[bytes]: ... + def splitlines(self, keepends: bool = ...) -> List[bytes]: ... + def startswith( + self, + __prefix: Union[bytes, Tuple[bytes, ...]], + __start: Optional[SupportsIndex] = ..., + __end: Optional[SupportsIndex] = ..., + ) -> bool: ... + def strip(self, __bytes: Optional[bytes] = ...) -> bytes: ... + def swapcase(self) -> bytes: ... + def title(self) -> bytes: ... + def translate(self, __table: Optional[bytes], delete: bytes = ...) -> bytes: ... + def upper(self) -> bytes: ... + def zfill(self, __width: SupportsIndex) -> bytes: ... + @classmethod + def fromhex(cls, __s: str) -> bytes: ... + @staticmethod + def maketrans(__frm: bytes, __to: bytes) -> bytes: ... + def __len__(self) -> int: ... + def __iter__(self) -> Iterator[int]: ... + def __str__(self) -> str: ... + def __repr__(self) -> str: ... + def __hash__(self) -> int: ... + @overload + def __getitem__(self, i: SupportsIndex) -> int: ... + @overload + def __getitem__(self, s: slice) -> bytes: ... + def __add__(self, s: bytes) -> bytes: ... + def __mul__(self, n: SupportsIndex) -> bytes: ... + def __rmul__(self, n: SupportsIndex) -> bytes: ... + def __mod__(self, value: Any) -> bytes: ... + # Incompatible with Sequence.__contains__ + def __contains__(self, o: SupportsIndex | bytes) -> bool: ... # type: ignore + def __eq__(self, x: object) -> bool: ... + def __ne__(self, x: object) -> bool: ... + def __lt__(self, x: bytes) -> bool: ... + def __le__(self, x: bytes) -> bool: ... + def __gt__(self, x: bytes) -> bool: ... + def __ge__(self, x: bytes) -> bool: ... + def __getnewargs__(self) -> Tuple[bytes]: ... + +class bytearray(MutableSequence[int], ByteString): + @overload + def __init__(self) -> None: ... + @overload + def __init__(self, ints: Iterable[SupportsIndex]) -> None: ... + @overload + def __init__(self, string: str, encoding: str, errors: str = ...) -> None: ... + @overload + def __init__(self, length: SupportsIndex) -> None: ... + def append(self, __item: SupportsIndex) -> None: ... + def capitalize(self) -> bytearray: ... + def center(self, __width: SupportsIndex, __fillchar: bytes = ...) -> bytearray: ... + def count( + self, __sub: bytes | SupportsIndex, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... + ) -> int: ... + def copy(self) -> bytearray: ... + def decode(self, encoding: str = ..., errors: str = ...) -> str: ... + def endswith( + self, + __suffix: Union[bytes, Tuple[bytes, ...]], + __start: Optional[SupportsIndex] = ..., + __end: Optional[SupportsIndex] = ..., + ) -> bool: ... + if sys.version_info >= (3, 8): + def expandtabs(self, tabsize: SupportsIndex = ...) -> bytearray: ... + else: + def expandtabs(self, tabsize: int = ...) -> bytearray: ... + def extend(self, __iterable_of_ints: Iterable[SupportsIndex]) -> None: ... + def find( + self, __sub: bytes | SupportsIndex, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... + ) -> int: ... + if sys.version_info >= (3, 8): + def hex(self, sep: Union[str, bytes] = ..., bytes_per_sep: SupportsIndex = ...) -> str: ... + else: + def hex(self) -> str: ... + def index( + self, __sub: bytes | SupportsIndex, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... + ) -> int: ... + def insert(self, __index: SupportsIndex, __item: SupportsIndex) -> None: ... + def isalnum(self) -> bool: ... + def isalpha(self) -> bool: ... + if sys.version_info >= (3, 7): + def isascii(self) -> bool: ... + def isdigit(self) -> bool: ... + def islower(self) -> bool: ... + def isspace(self) -> bool: ... + def istitle(self) -> bool: ... + def isupper(self) -> bool: ... + def join(self, __iterable_of_bytes: Iterable[Union[ByteString, memoryview]]) -> bytearray: ... + def ljust(self, __width: SupportsIndex, __fillchar: bytes = ...) -> bytearray: ... + def lower(self) -> bytearray: ... + def lstrip(self, __bytes: Optional[bytes] = ...) -> bytearray: ... + def partition(self, __sep: bytes) -> Tuple[bytearray, bytearray, bytearray]: ... + if sys.version_info >= (3, 9): + def removeprefix(self, __prefix: bytes) -> bytearray: ... + def removesuffix(self, __suffix: bytes) -> bytearray: ... + def replace(self, __old: bytes, __new: bytes, __count: SupportsIndex = ...) -> bytearray: ... + def rfind( + self, __sub: bytes | SupportsIndex, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... + ) -> int: ... + def rindex( + self, __sub: bytes | SupportsIndex, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... + ) -> int: ... + def rjust(self, __width: SupportsIndex, __fillchar: bytes = ...) -> bytearray: ... + def rpartition(self, __sep: bytes) -> Tuple[bytearray, bytearray, bytearray]: ... + def rsplit(self, sep: Optional[bytes] = ..., maxsplit: SupportsIndex = ...) -> List[bytearray]: ... + def rstrip(self, __bytes: Optional[bytes] = ...) -> bytearray: ... + def split(self, sep: Optional[bytes] = ..., maxsplit: SupportsIndex = ...) -> List[bytearray]: ... + def splitlines(self, keepends: bool = ...) -> List[bytearray]: ... + def startswith( + self, + __prefix: Union[bytes, Tuple[bytes, ...]], + __start: Optional[SupportsIndex] = ..., + __end: Optional[SupportsIndex] = ..., + ) -> bool: ... + def strip(self, __bytes: Optional[bytes] = ...) -> bytearray: ... + def swapcase(self) -> bytearray: ... + def title(self) -> bytearray: ... + def translate(self, __table: Optional[bytes], delete: bytes = ...) -> bytearray: ... + def upper(self) -> bytearray: ... + def zfill(self, __width: SupportsIndex) -> bytearray: ... + @classmethod + def fromhex(cls, __string: str) -> bytearray: ... + @staticmethod + def maketrans(__frm: bytes, __to: bytes) -> bytes: ... + def __len__(self) -> int: ... + def __iter__(self) -> Iterator[int]: ... + def __str__(self) -> str: ... + def __repr__(self) -> str: ... + __hash__: None # type: ignore + @overload + def __getitem__(self, i: SupportsIndex) -> int: ... + @overload + def __getitem__(self, s: slice) -> bytearray: ... + @overload + def __setitem__(self, i: SupportsIndex, x: SupportsIndex) -> None: ... + @overload + def __setitem__(self, s: slice, x: Iterable[SupportsIndex] | bytes) -> None: ... + def __delitem__(self, i: SupportsIndex | slice) -> None: ... + def __add__(self, s: bytes) -> bytearray: ... + def __iadd__(self, s: Iterable[int]) -> bytearray: ... + def __mul__(self, n: SupportsIndex) -> bytearray: ... + def __rmul__(self, n: SupportsIndex) -> bytearray: ... + def __imul__(self, n: SupportsIndex) -> bytearray: ... + def __mod__(self, value: Any) -> bytes: ... + # Incompatible with Sequence.__contains__ + def __contains__(self, o: SupportsIndex | bytes) -> bool: ... # type: ignore + def __eq__(self, x: object) -> bool: ... + def __ne__(self, x: object) -> bool: ... + def __lt__(self, x: bytes) -> bool: ... + def __le__(self, x: bytes) -> bool: ... + def __gt__(self, x: bytes) -> bool: ... + def __ge__(self, x: bytes) -> bool: ... + +class memoryview(Sized, Sequence[int]): + format: str + itemsize: int + shape: Optional[Tuple[int, ...]] + strides: Optional[Tuple[int, ...]] + suboffsets: Optional[Tuple[int, ...]] + readonly: bool + ndim: int + + obj: Union[bytes, bytearray] + c_contiguous: bool + f_contiguous: bool + contiguous: bool + nbytes: int + def __init__(self, obj: ReadableBuffer) -> None: ... + def __enter__(self: Self) -> Self: ... + def __exit__( + self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], exc_tb: Optional[TracebackType] + ) -> None: ... + def cast(self, format: str, shape: Union[List[int], Tuple[int]] = ...) -> memoryview: ... + @overload + def __getitem__(self, i: SupportsIndex) -> int: ... + @overload + def __getitem__(self, s: slice) -> memoryview: ... + def __contains__(self, x: object) -> bool: ... + def __iter__(self) -> Iterator[int]: ... + def __len__(self) -> int: ... + @overload + def __setitem__(self, s: slice, o: bytes) -> None: ... + @overload + def __setitem__(self, i: SupportsIndex, o: SupportsIndex) -> None: ... + if sys.version_info >= (3, 8): + def tobytes(self, order: Optional[Literal["C", "F", "A"]] = ...) -> bytes: ... + else: + def tobytes(self) -> bytes: ... + def tolist(self) -> List[int]: ... + if sys.version_info >= (3, 8): + def toreadonly(self) -> memoryview: ... + def release(self) -> None: ... + if sys.version_info >= (3, 8): + def hex(self, sep: Union[str, bytes] = ..., bytes_per_sep: SupportsIndex = ...) -> str: ... + else: + def hex(self) -> str: ... + +@final +class bool(int): + def __new__(cls: Type[_T], __o: object = ...) -> _T: ... + @overload + def __and__(self, x: bool) -> bool: ... + @overload + def __and__(self, x: int) -> int: ... + @overload + def __or__(self, x: bool) -> bool: ... + @overload + def __or__(self, x: int) -> int: ... + @overload + def __xor__(self, x: bool) -> bool: ... + @overload + def __xor__(self, x: int) -> int: ... + @overload + def __rand__(self, x: bool) -> bool: ... + @overload + def __rand__(self, x: int) -> int: ... + @overload + def __ror__(self, x: bool) -> bool: ... + @overload + def __ror__(self, x: int) -> int: ... + @overload + def __rxor__(self, x: bool) -> bool: ... + @overload + def __rxor__(self, x: int) -> int: ... + def __getnewargs__(self) -> Tuple[int]: ... + +class slice(object): + start: Any + step: Any + stop: Any + @overload + def __init__(self, stop: Any) -> None: ... + @overload + def __init__(self, start: Any, stop: Any, step: Any = ...) -> None: ... + __hash__: None # type: ignore + def indices(self, len: SupportsIndex) -> Tuple[int, int, int]: ... + +class tuple(Sequence[_T_co], Generic[_T_co]): + def __new__(cls: Type[_T], iterable: Iterable[_T_co] = ...) -> _T: ... + def __len__(self) -> int: ... + def __contains__(self, x: object) -> bool: ... + @overload + def __getitem__(self, x: int) -> _T_co: ... + @overload + def __getitem__(self, x: slice) -> Tuple[_T_co, ...]: ... + def __iter__(self) -> Iterator[_T_co]: ... + def __lt__(self, x: Tuple[_T_co, ...]) -> bool: ... + def __le__(self, x: Tuple[_T_co, ...]) -> bool: ... + def __gt__(self, x: Tuple[_T_co, ...]) -> bool: ... + def __ge__(self, x: Tuple[_T_co, ...]) -> bool: ... + @overload + def __add__(self, x: Tuple[_T_co, ...]) -> Tuple[_T_co, ...]: ... + @overload + def __add__(self, x: Tuple[_T, ...]) -> Tuple[Union[_T_co, _T], ...]: ... + def __mul__(self, n: SupportsIndex) -> Tuple[_T_co, ...]: ... + def __rmul__(self, n: SupportsIndex) -> Tuple[_T_co, ...]: ... + def count(self, __value: Any) -> int: ... + def index(self, __value: Any, __start: SupportsIndex = ..., __stop: SupportsIndex = ...) -> int: ... + if sys.version_info >= (3, 9): + def __class_getitem__(cls, item: Any) -> GenericAlias: ... + +class function: + # TODO not defined in builtins! + __name__: str + __module__: str + __code__: CodeType + __qualname__: str + __annotations__: Dict[str, Any] + +class list(MutableSequence[_T], Generic[_T]): + @overload + def __init__(self) -> None: ... + @overload + def __init__(self, iterable: Iterable[_T]) -> None: ... + def clear(self) -> None: ... + def copy(self) -> List[_T]: ... + def append(self, __object: _T) -> None: ... + def extend(self, __iterable: Iterable[_T]) -> None: ... + def pop(self, __index: SupportsIndex = ...) -> _T: ... + def index(self, __value: _T, __start: SupportsIndex = ..., __stop: SupportsIndex = ...) -> int: ... + def count(self, __value: _T) -> int: ... + def insert(self, __index: SupportsIndex, __object: _T) -> None: ... + def remove(self, __value: _T) -> None: ... + def reverse(self) -> None: ... + @overload + def sort(self: List[SupportsLessThanT], *, key: None = ..., reverse: bool = ...) -> None: ... + @overload + def sort(self, *, key: Callable[[_T], SupportsLessThan], reverse: bool = ...) -> None: ... + def __len__(self) -> int: ... + def __iter__(self) -> Iterator[_T]: ... + def __str__(self) -> str: ... + __hash__: None # type: ignore + @overload + def __getitem__(self, i: SupportsIndex) -> _T: ... + @overload + def __getitem__(self, s: slice) -> List[_T]: ... + @overload + def __setitem__(self, i: SupportsIndex, o: _T) -> None: ... + @overload + def __setitem__(self, s: slice, o: Iterable[_T]) -> None: ... + def __delitem__(self, i: Union[SupportsIndex, slice]) -> None: ... + def __add__(self, x: List[_T]) -> List[_T]: ... + def __iadd__(self: _S, x: Iterable[_T]) -> _S: ... + def __mul__(self, n: SupportsIndex) -> List[_T]: ... + def __rmul__(self, n: SupportsIndex) -> List[_T]: ... + def __imul__(self: _S, n: SupportsIndex) -> _S: ... + def __contains__(self, o: object) -> bool: ... + def __reversed__(self) -> Iterator[_T]: ... + def __gt__(self, x: List[_T]) -> bool: ... + def __ge__(self, x: List[_T]) -> bool: ... + def __lt__(self, x: List[_T]) -> bool: ... + def __le__(self, x: List[_T]) -> bool: ... + if sys.version_info >= (3, 9): + def __class_getitem__(cls, item: Any) -> GenericAlias: ... + +class dict(MutableMapping[_KT, _VT], Generic[_KT, _VT]): + @overload + def __init__(self: Dict[_KT, _VT]) -> None: ... + @overload + def __init__(self: Dict[str, _VT], **kwargs: _VT) -> None: ... + @overload + def __init__(self, map: SupportsKeysAndGetItem[_KT, _VT], **kwargs: _VT) -> None: ... + @overload + def __init__(self, iterable: Iterable[Tuple[_KT, _VT]], **kwargs: _VT) -> None: ... + def __new__(cls: Type[_T1], *args: Any, **kwargs: Any) -> _T1: ... + def clear(self) -> None: ... + def copy(self) -> Dict[_KT, _VT]: ... + def popitem(self) -> Tuple[_KT, _VT]: ... + def setdefault(self, __key: _KT, __default: _VT = ...) -> _VT: ... + @overload + def update(self, __m: Mapping[_KT, _VT], **kwargs: _VT) -> None: ... + @overload + def update(self, __m: Iterable[Tuple[_KT, _VT]], **kwargs: _VT) -> None: ... + @overload + def update(self, **kwargs: _VT) -> None: ... + def keys(self) -> KeysView[_KT]: ... + def values(self) -> ValuesView[_VT]: ... + def items(self) -> ItemsView[_KT, _VT]: ... + @classmethod + @overload + def fromkeys(cls, __iterable: Iterable[_T], __value: None = ...) -> dict[_T, Optional[Any]]: ... + @classmethod + @overload + def fromkeys(cls, __iterable: Iterable[_T], __value: _S) -> dict[_T, _S]: ... + def __len__(self) -> int: ... + def __getitem__(self, k: _KT) -> _VT: ... + def __setitem__(self, k: _KT, v: _VT) -> None: ... + def __delitem__(self, v: _KT) -> None: ... + def __iter__(self) -> Iterator[_KT]: ... + if sys.version_info >= (3, 8): + def __reversed__(self) -> Iterator[_KT]: ... + def __str__(self) -> str: ... + __hash__: None # type: ignore + if sys.version_info >= (3, 9): + def __class_getitem__(cls, item: Any) -> GenericAlias: ... + def __or__(self, __value: Mapping[_T1, _T2]) -> Dict[Union[_KT, _T1], Union[_VT, _T2]]: ... + def __ror__(self, __value: Mapping[_T1, _T2]) -> Dict[Union[_KT, _T1], Union[_VT, _T2]]: ... + def __ior__(self, __value: Mapping[_KT, _VT]) -> Dict[_KT, _VT]: ... # type: ignore + +class set(MutableSet[_T], Generic[_T]): + def __init__(self, iterable: Iterable[_T] = ...) -> None: ... + def add(self, element: _T) -> None: ... + def clear(self) -> None: ... + def copy(self) -> Set[_T]: ... + def difference(self, *s: Iterable[Any]) -> Set[_T]: ... + def difference_update(self, *s: Iterable[Any]) -> None: ... + def discard(self, element: _T) -> None: ... + def intersection(self, *s: Iterable[Any]) -> Set[_T]: ... + def intersection_update(self, *s: Iterable[Any]) -> None: ... + def isdisjoint(self, s: Iterable[Any]) -> bool: ... + def issubset(self, s: Iterable[Any]) -> bool: ... + def issuperset(self, s: Iterable[Any]) -> bool: ... + def pop(self) -> _T: ... + def remove(self, element: _T) -> None: ... + def symmetric_difference(self, s: Iterable[_T]) -> Set[_T]: ... + def symmetric_difference_update(self, s: Iterable[_T]) -> None: ... + def union(self, *s: Iterable[_T]) -> Set[_T]: ... + def update(self, *s: Iterable[_T]) -> None: ... + def __len__(self) -> int: ... + def __contains__(self, o: object) -> bool: ... + def __iter__(self) -> Iterator[_T]: ... + def __str__(self) -> str: ... + def __and__(self, s: AbstractSet[object]) -> Set[_T]: ... + def __iand__(self, s: AbstractSet[object]) -> Set[_T]: ... + def __or__(self, s: AbstractSet[_S]) -> Set[Union[_T, _S]]: ... + def __ior__(self, s: AbstractSet[_S]) -> Set[Union[_T, _S]]: ... + def __sub__(self, s: AbstractSet[Optional[_T]]) -> Set[_T]: ... + def __isub__(self, s: AbstractSet[Optional[_T]]) -> Set[_T]: ... + def __xor__(self, s: AbstractSet[_S]) -> Set[Union[_T, _S]]: ... + def __ixor__(self, s: AbstractSet[_S]) -> Set[Union[_T, _S]]: ... + def __le__(self, s: AbstractSet[object]) -> bool: ... + def __lt__(self, s: AbstractSet[object]) -> bool: ... + def __ge__(self, s: AbstractSet[object]) -> bool: ... + def __gt__(self, s: AbstractSet[object]) -> bool: ... + __hash__: None # type: ignore + if sys.version_info >= (3, 9): + def __class_getitem__(cls, item: Any) -> GenericAlias: ... + +class frozenset(AbstractSet[_T_co], Generic[_T_co]): + def __init__(self, iterable: Iterable[_T_co] = ...) -> None: ... + def copy(self) -> FrozenSet[_T_co]: ... + def difference(self, *s: Iterable[object]) -> FrozenSet[_T_co]: ... + def intersection(self, *s: Iterable[object]) -> FrozenSet[_T_co]: ... + def isdisjoint(self, s: Iterable[_T_co]) -> bool: ... + def issubset(self, s: Iterable[object]) -> bool: ... + def issuperset(self, s: Iterable[object]) -> bool: ... + def symmetric_difference(self, s: Iterable[_T_co]) -> FrozenSet[_T_co]: ... + def union(self, *s: Iterable[_T_co]) -> FrozenSet[_T_co]: ... + def __len__(self) -> int: ... + def __contains__(self, o: object) -> bool: ... + def __iter__(self) -> Iterator[_T_co]: ... + def __str__(self) -> str: ... + def __and__(self, s: AbstractSet[_T_co]) -> FrozenSet[_T_co]: ... + def __or__(self, s: AbstractSet[_S]) -> FrozenSet[Union[_T_co, _S]]: ... + def __sub__(self, s: AbstractSet[_T_co]) -> FrozenSet[_T_co]: ... + def __xor__(self, s: AbstractSet[_S]) -> FrozenSet[Union[_T_co, _S]]: ... + def __le__(self, s: AbstractSet[object]) -> bool: ... + def __lt__(self, s: AbstractSet[object]) -> bool: ... + def __ge__(self, s: AbstractSet[object]) -> bool: ... + def __gt__(self, s: AbstractSet[object]) -> bool: ... + if sys.version_info >= (3, 9): + def __class_getitem__(cls, item: Any) -> GenericAlias: ... + +class enumerate(Iterator[Tuple[int, _T]], Generic[_T]): + def __init__(self, iterable: Iterable[_T], start: int = ...) -> None: ... + def __iter__(self) -> Iterator[Tuple[int, _T]]: ... + def __next__(self) -> Tuple[int, _T]: ... + if sys.version_info >= (3, 9): + def __class_getitem__(cls, item: Any) -> GenericAlias: ... + +class range(Sequence[int]): + start: int + stop: int + step: int + @overload + def __init__(self, stop: SupportsIndex) -> None: ... + @overload + def __init__(self, start: SupportsIndex, stop: SupportsIndex, step: SupportsIndex = ...) -> None: ... + def count(self, value: int) -> int: ... + def index(self, value: int) -> int: ... # type: ignore + def __len__(self) -> int: ... + def __contains__(self, o: object) -> bool: ... + def __iter__(self) -> Iterator[int]: ... + @overload + def __getitem__(self, i: SupportsIndex) -> int: ... + @overload + def __getitem__(self, s: slice) -> range: ... + def __repr__(self) -> str: ... + def __reversed__(self) -> Iterator[int]: ... + +class property(object): + fget: Optional[Callable[[Any], Any]] + fset: Optional[Callable[[Any, Any], None]] + fdel: Optional[Callable[[Any], None]] + def __init__( + self, + fget: Optional[Callable[[Any], Any]] = ..., + fset: Optional[Callable[[Any, Any], None]] = ..., + fdel: Optional[Callable[[Any], None]] = ..., + doc: Optional[str] = ..., + ) -> None: ... + def getter(self, fget: Callable[[Any], Any]) -> property: ... + def setter(self, fset: Callable[[Any, Any], None]) -> property: ... + def deleter(self, fdel: Callable[[Any], None]) -> property: ... + def __get__(self, obj: Any, type: Optional[type] = ...) -> Any: ... + def __set__(self, obj: Any, value: Any) -> None: ... + def __delete__(self, obj: Any) -> None: ... + +class _NotImplementedType(Any): # type: ignore + # A little weird, but typing the __call__ as NotImplemented makes the error message + # for NotImplemented() much better + __call__: NotImplemented # type: ignore + +NotImplemented: _NotImplementedType + +def abs(__x: SupportsAbs[_T]) -> _T: ... +def all(__iterable: Iterable[object]) -> bool: ... +def any(__iterable: Iterable[object]) -> bool: ... +def ascii(__obj: object) -> str: ... +def bin(__number: Union[int, SupportsIndex]) -> str: ... + +if sys.version_info >= (3, 7): + def breakpoint(*args: Any, **kws: Any) -> None: ... + +def callable(__obj: object) -> bool: ... +def chr(__i: int) -> str: ... + +# We define this here instead of using os.PathLike to avoid import cycle issues. +# See https://github.com/python/typeshed/pull/991#issuecomment-288160993 +_AnyStr_co = TypeVar("_AnyStr_co", str, bytes, covariant=True) + +class _PathLike(Protocol[_AnyStr_co]): + def __fspath__(self) -> _AnyStr_co: ... + +if sys.version_info >= (3, 10): + def aiter(__iterable: AsyncIterable[_T]) -> AsyncIterator[_T]: ... + @overload + async def anext(__i: AsyncIterator[_T]) -> _T: ... + @overload + async def anext(__i: AsyncIterator[_T], default: _VT) -> Union[_T, _VT]: ... + +if sys.version_info >= (3, 8): + def compile( + source: Union[str, bytes, mod, AST], + filename: Union[str, bytes, _PathLike[Any]], + mode: str, + flags: int = ..., + dont_inherit: int = ..., + optimize: int = ..., + *, + _feature_version: int = ..., + ) -> Any: ... + +else: + def compile( + source: Union[str, bytes, mod, AST], + filename: Union[str, bytes, _PathLike[Any]], + mode: str, + flags: int = ..., + dont_inherit: int = ..., + optimize: int = ..., + ) -> Any: ... + +def copyright() -> None: ... +def credits() -> None: ... +def delattr(__obj: Any, __name: str) -> None: ... +def dir(__o: object = ...) -> List[str]: ... +@overload +def divmod(__x: SupportsDivMod[_T_contra, _T_co], __y: _T_contra) -> _T_co: ... +@overload +def divmod(__x: _T_contra, __y: SupportsRDivMod[_T_contra, _T_co]) -> _T_co: ... +def eval( + __source: Union[str, bytes, CodeType], __globals: Optional[Dict[str, Any]] = ..., __locals: Optional[Mapping[str, Any]] = ... +) -> Any: ... +def exec( + __source: Union[str, bytes, CodeType], __globals: Optional[Dict[str, Any]] = ..., __locals: Optional[Mapping[str, Any]] = ... +) -> Any: ... +def exit(code: object = ...) -> NoReturn: ... + +class filter(Iterator[_T], Generic[_T]): + @overload + def __init__(self, __function: None, __iterable: Iterable[Optional[_T]]) -> None: ... + @overload + def __init__(self, __function: Callable[[_T], Any], __iterable: Iterable[_T]) -> None: ... + def __iter__(self) -> Iterator[_T]: ... + def __next__(self) -> _T: ... + +def format(__value: object, __format_spec: str = ...) -> str: ... # TODO unicode +@overload +def getattr(__o: Any, name: str) -> Any: ... + +# While technically covered by the last overload, spelling out the types for None and bool +# help mypy out in some tricky situations involving type context (aka bidirectional inference) +@overload +def getattr(__o: Any, name: str, __default: None) -> Optional[Any]: ... +@overload +def getattr(__o: Any, name: str, __default: bool) -> Union[Any, bool]: ... +@overload +def getattr(__o: Any, name: str, __default: _T) -> Union[Any, _T]: ... +def globals() -> Dict[str, Any]: ... +def hasattr(__obj: Any, __name: str) -> bool: ... +def hash(__obj: object) -> int: ... +def help(*args: Any, **kwds: Any) -> None: ... +def hex(__number: Union[int, SupportsIndex]) -> str: ... +def id(__obj: object) -> int: ... +def input(__prompt: Any = ...) -> str: ... +@overload +def iter(__iterable: Iterable[_T]) -> Iterator[_T]: ... +@overload +def iter(__function: Callable[[], Optional[_T]], __sentinel: None) -> Iterator[_T]: ... +@overload +def iter(__function: Callable[[], _T], __sentinel: Any) -> Iterator[_T]: ... + +if sys.version_info >= (3, 10): + def isinstance( + __obj: object, __class_or_tuple: Union[type, types.Union, Tuple[Union[type, types.Union, Tuple[Any, ...]], ...]] + ) -> bool: ... + def issubclass( + __cls: type, __class_or_tuple: Union[type, types.Union, Tuple[Union[type, types.Union, Tuple[Any, ...]], ...]] + ) -> bool: ... + +else: + def isinstance(__obj: object, __class_or_tuple: Union[type, Tuple[Union[type, Tuple[Any, ...]], ...]]) -> bool: ... + def issubclass(__cls: type, __class_or_tuple: Union[type, Tuple[Union[type, Tuple[Any, ...]], ...]]) -> bool: ... + +def len(__obj: Sized) -> int: ... +def license() -> None: ... +def locals() -> Dict[str, Any]: ... + +class map(Iterator[_S], Generic[_S]): + @overload + def __init__(self, __func: Callable[[_T1], _S], __iter1: Iterable[_T1]) -> None: ... + @overload + def __init__(self, __func: Callable[[_T1, _T2], _S], __iter1: Iterable[_T1], __iter2: Iterable[_T2]) -> None: ... + @overload + def __init__( + self, __func: Callable[[_T1, _T2, _T3], _S], __iter1: Iterable[_T1], __iter2: Iterable[_T2], __iter3: Iterable[_T3] + ) -> None: ... + @overload + def __init__( + self, + __func: Callable[[_T1, _T2, _T3, _T4], _S], + __iter1: Iterable[_T1], + __iter2: Iterable[_T2], + __iter3: Iterable[_T3], + __iter4: Iterable[_T4], + ) -> None: ... + @overload + def __init__( + self, + __func: Callable[[_T1, _T2, _T3, _T4, _T5], _S], + __iter1: Iterable[_T1], + __iter2: Iterable[_T2], + __iter3: Iterable[_T3], + __iter4: Iterable[_T4], + __iter5: Iterable[_T5], + ) -> None: ... + @overload + def __init__( + self, + __func: Callable[..., _S], + __iter1: Iterable[Any], + __iter2: Iterable[Any], + __iter3: Iterable[Any], + __iter4: Iterable[Any], + __iter5: Iterable[Any], + __iter6: Iterable[Any], + *iterables: Iterable[Any], + ) -> None: ... + def __iter__(self) -> Iterator[_S]: ... + def __next__(self) -> _S: ... + +@overload +def max( + __arg1: SupportsLessThanT, __arg2: SupportsLessThanT, *_args: SupportsLessThanT, key: None = ... +) -> SupportsLessThanT: ... +@overload +def max(__arg1: _T, __arg2: _T, *_args: _T, key: Callable[[_T], SupportsLessThan]) -> _T: ... +@overload +def max(__iterable: Iterable[SupportsLessThanT], *, key: None = ...) -> SupportsLessThanT: ... +@overload +def max(__iterable: Iterable[_T], *, key: Callable[[_T], SupportsLessThan]) -> _T: ... +@overload +def max(__iterable: Iterable[SupportsLessThanT], *, key: None = ..., default: _T) -> Union[SupportsLessThanT, _T]: ... +@overload +def max(__iterable: Iterable[_T1], *, key: Callable[[_T1], SupportsLessThan], default: _T2) -> Union[_T1, _T2]: ... +@overload +def min( + __arg1: SupportsLessThanT, __arg2: SupportsLessThanT, *_args: SupportsLessThanT, key: None = ... +) -> SupportsLessThanT: ... +@overload +def min(__arg1: _T, __arg2: _T, *_args: _T, key: Callable[[_T], SupportsLessThan]) -> _T: ... +@overload +def min(__iterable: Iterable[SupportsLessThanT], *, key: None = ...) -> SupportsLessThanT: ... +@overload +def min(__iterable: Iterable[_T], *, key: Callable[[_T], SupportsLessThan]) -> _T: ... +@overload +def min(__iterable: Iterable[SupportsLessThanT], *, key: None = ..., default: _T) -> Union[SupportsLessThanT, _T]: ... +@overload +def min(__iterable: Iterable[_T1], *, key: Callable[[_T1], SupportsLessThan], default: _T2) -> Union[_T1, _T2]: ... +@overload +def next(__i: Iterator[_T]) -> _T: ... +@overload +def next(__i: Iterator[_T], default: _VT) -> Union[_T, _VT]: ... +def oct(__number: Union[int, SupportsIndex]) -> str: ... + +_OpenFile = Union[StrOrBytesPath, int] +_Opener = Callable[[str, int], int] + +# Text mode: always returns a TextIOWrapper +@overload +def open( + file: _OpenFile, + mode: OpenTextMode = ..., + buffering: int = ..., + encoding: Optional[str] = ..., + errors: Optional[str] = ..., + newline: Optional[str] = ..., + closefd: bool = ..., + opener: Optional[_Opener] = ..., +) -> TextIOWrapper: ... + +# Unbuffered binary mode: returns a FileIO +@overload +def open( + file: _OpenFile, + mode: OpenBinaryMode, + buffering: Literal[0], + encoding: None = ..., + errors: None = ..., + newline: None = ..., + closefd: bool = ..., + opener: Optional[_Opener] = ..., +) -> FileIO: ... + +# Buffering is on: return BufferedRandom, BufferedReader, or BufferedWriter +@overload +def open( + file: _OpenFile, + mode: OpenBinaryModeUpdating, + buffering: Literal[-1, 1] = ..., + encoding: None = ..., + errors: None = ..., + newline: None = ..., + closefd: bool = ..., + opener: Optional[_Opener] = ..., +) -> BufferedRandom: ... +@overload +def open( + file: _OpenFile, + mode: OpenBinaryModeWriting, + buffering: Literal[-1, 1] = ..., + encoding: None = ..., + errors: None = ..., + newline: None = ..., + closefd: bool = ..., + opener: Optional[_Opener] = ..., +) -> BufferedWriter: ... +@overload +def open( + file: _OpenFile, + mode: OpenBinaryModeReading, + buffering: Literal[-1, 1] = ..., + encoding: None = ..., + errors: None = ..., + newline: None = ..., + closefd: bool = ..., + opener: Optional[_Opener] = ..., +) -> BufferedReader: ... + +# Buffering cannot be determined: fall back to BinaryIO +@overload +def open( + file: _OpenFile, + mode: OpenBinaryMode, + buffering: int, + encoding: None = ..., + errors: None = ..., + newline: None = ..., + closefd: bool = ..., + opener: Optional[_Opener] = ..., +) -> BinaryIO: ... + +# Fallback if mode is not specified +@overload +def open( + file: _OpenFile, + mode: str, + buffering: int = ..., + encoding: Optional[str] = ..., + errors: Optional[str] = ..., + newline: Optional[str] = ..., + closefd: bool = ..., + opener: Optional[_Opener] = ..., +) -> IO[Any]: ... +def ord(__c: Union[str, bytes]) -> int: ... +def print( + *values: object, + sep: Optional[str] = ..., + end: Optional[str] = ..., + file: Optional[SupportsWrite[str]] = ..., + flush: bool = ..., +) -> None: ... + +_E = TypeVar("_E", contravariant=True) +_M = TypeVar("_M", contravariant=True) + +class _SupportsPow2(Protocol[_E, _T_co]): + def __pow__(self, __other: _E) -> _T_co: ... + +class _SupportsPow3(Protocol[_E, _M, _T_co]): + def __pow__(self, __other: _E, __modulo: _M) -> _T_co: ... + +if sys.version_info >= (3, 8): + @overload + def pow(base: int, exp: int, mod: None = ...) -> Any: ... # returns int or float depending on whether exp is non-negative + @overload + def pow(base: int, exp: int, mod: int) -> int: ... + @overload + def pow(base: float, exp: float, mod: None = ...) -> float: ... + @overload + def pow(base: _SupportsPow2[_E, _T_co], exp: _E) -> _T_co: ... + @overload + def pow(base: _SupportsPow3[_E, _M, _T_co], exp: _E, mod: _M) -> _T_co: ... + +else: + @overload + def pow( + __base: int, __exp: int, __mod: None = ... + ) -> Any: ... # returns int or float depending on whether exp is non-negative + @overload + def pow(__base: int, __exp: int, __mod: int) -> int: ... + @overload + def pow(__base: float, __exp: float, __mod: None = ...) -> float: ... + @overload + def pow(__base: _SupportsPow2[_E, _T_co], __exp: _E) -> _T_co: ... + @overload + def pow(__base: _SupportsPow3[_E, _M, _T_co], __exp: _E, __mod: _M) -> _T_co: ... + +def quit(code: object = ...) -> NoReturn: ... + +class reversed(Iterator[_T], Generic[_T]): + @overload + def __init__(self, __sequence: Sequence[_T]) -> None: ... + @overload + def __init__(self, __sequence: Reversible[_T]) -> None: ... + def __iter__(self) -> Iterator[_T]: ... + def __next__(self) -> _T: ... + +def repr(__obj: object) -> str: ... +@overload +def round(number: SupportsRound[Any]) -> int: ... +@overload +def round(number: SupportsRound[Any], ndigits: None) -> int: ... +@overload +def round(number: SupportsRound[_T], ndigits: SupportsIndex) -> _T: ... +def setattr(__obj: Any, __name: str, __value: Any) -> None: ... +@overload +def sorted(__iterable: Iterable[SupportsLessThanT], *, key: None = ..., reverse: bool = ...) -> List[SupportsLessThanT]: ... +@overload +def sorted(__iterable: Iterable[_T], *, key: Callable[[_T], SupportsLessThan], reverse: bool = ...) -> List[_T]: ... + +if sys.version_info >= (3, 8): + @overload + def sum(__iterable: Iterable[_T]) -> Union[_T, int]: ... + @overload + def sum(__iterable: Iterable[_T], start: _S) -> Union[_T, _S]: ... + +else: + @overload + def sum(__iterable: Iterable[_T]) -> Union[_T, int]: ... + @overload + def sum(__iterable: Iterable[_T], __start: _S) -> Union[_T, _S]: ... + +def vars(__object: Any = ...) -> Dict[str, Any]: ... + +class zip(Iterator[_T_co], Generic[_T_co]): + @overload + def __new__(cls, __iter1: Iterable[_T1]) -> zip[Tuple[_T1]]: ... + @overload + def __new__(cls, __iter1: Iterable[_T1], __iter2: Iterable[_T2]) -> zip[Tuple[_T1, _T2]]: ... + @overload + def __new__(cls, __iter1: Iterable[_T1], __iter2: Iterable[_T2], __iter3: Iterable[_T3]) -> zip[Tuple[_T1, _T2, _T3]]: ... + @overload + def __new__( + cls, __iter1: Iterable[_T1], __iter2: Iterable[_T2], __iter3: Iterable[_T3], __iter4: Iterable[_T4] + ) -> zip[Tuple[_T1, _T2, _T3, _T4]]: ... + @overload + def __new__( + cls, + __iter1: Iterable[_T1], + __iter2: Iterable[_T2], + __iter3: Iterable[_T3], + __iter4: Iterable[_T4], + __iter5: Iterable[_T5], + ) -> zip[Tuple[_T1, _T2, _T3, _T4, _T5]]: ... + @overload + def __new__( + cls, + __iter1: Iterable[Any], + __iter2: Iterable[Any], + __iter3: Iterable[Any], + __iter4: Iterable[Any], + __iter5: Iterable[Any], + __iter6: Iterable[Any], + *iterables: Iterable[Any], + ) -> zip[Tuple[Any, ...]]: ... + def __iter__(self) -> Iterator[_T_co]: ... + def __next__(self) -> _T_co: ... + +def __import__( + name: str, + globals: Optional[Mapping[str, Any]] = ..., + locals: Optional[Mapping[str, Any]] = ..., + fromlist: Sequence[str] = ..., + level: int = ..., +) -> Any: ... + +# Actually the type of Ellipsis is , but since it's +# not exposed anywhere under that name, we make it private here. +class ellipsis: ... + +Ellipsis: ellipsis + +class BaseException(object): + args: Tuple[Any, ...] + __cause__: Optional[BaseException] + __context__: Optional[BaseException] + __suppress_context__: bool + __traceback__: Optional[TracebackType] + def __init__(self, *args: object) -> None: ... + def __str__(self) -> str: ... + def __repr__(self) -> str: ... + def with_traceback(self: _TBE, tb: Optional[TracebackType]) -> _TBE: ... + +class GeneratorExit(BaseException): ... +class KeyboardInterrupt(BaseException): ... + +class SystemExit(BaseException): + code: int + +class Exception(BaseException): ... + +class StopIteration(Exception): + value: Any + +_StandardError = Exception + +class OSError(Exception): + errno: int + strerror: str + # filename, filename2 are actually Union[str, bytes, None] + filename: Any + filename2: Any + if sys.platform == "win32": + winerror: int + +EnvironmentError = OSError +IOError = OSError +if sys.platform == "win32": + WindowsError = OSError + +class ArithmeticError(_StandardError): ... +class AssertionError(_StandardError): ... + +class AttributeError(_StandardError): + if sys.version_info >= (3, 10): + name: str + obj: object + +class BufferError(_StandardError): ... +class EOFError(_StandardError): ... + +class ImportError(_StandardError): + def __init__(self, *args: object, name: Optional[str] = ..., path: Optional[str] = ...) -> None: ... + name: Optional[str] + path: Optional[str] + msg: str # undocumented + +class LookupError(_StandardError): ... +class MemoryError(_StandardError): ... + +class NameError(_StandardError): + if sys.version_info >= (3, 10): + name: str + +class ReferenceError(_StandardError): ... +class RuntimeError(_StandardError): ... + +class StopAsyncIteration(Exception): + value: Any + +class SyntaxError(_StandardError): + msg: str + lineno: Optional[int] + offset: Optional[int] + text: Optional[str] + filename: Optional[str] + if sys.version_info >= (3, 10): + end_lineno: Optional[int] + end_offset: Optional[int] + +class SystemError(_StandardError): ... +class TypeError(_StandardError): ... +class ValueError(_StandardError): ... +class FloatingPointError(ArithmeticError): ... +class OverflowError(ArithmeticError): ... +class ZeroDivisionError(ArithmeticError): ... +class ModuleNotFoundError(ImportError): ... +class IndexError(LookupError): ... +class KeyError(LookupError): ... +class UnboundLocalError(NameError): ... + +class BlockingIOError(OSError): + characters_written: int + +class ChildProcessError(OSError): ... +class ConnectionError(OSError): ... +class BrokenPipeError(ConnectionError): ... +class ConnectionAbortedError(ConnectionError): ... +class ConnectionRefusedError(ConnectionError): ... +class ConnectionResetError(ConnectionError): ... +class FileExistsError(OSError): ... +class FileNotFoundError(OSError): ... +class InterruptedError(OSError): ... +class IsADirectoryError(OSError): ... +class NotADirectoryError(OSError): ... +class PermissionError(OSError): ... +class ProcessLookupError(OSError): ... +class TimeoutError(OSError): ... +class NotImplementedError(RuntimeError): ... +class RecursionError(RuntimeError): ... +class IndentationError(SyntaxError): ... +class TabError(IndentationError): ... +class UnicodeError(ValueError): ... + +class UnicodeDecodeError(UnicodeError): + encoding: str + object: bytes + start: int + end: int + reason: str + def __init__(self, __encoding: str, __object: bytes, __start: int, __end: int, __reason: str) -> None: ... + +class UnicodeEncodeError(UnicodeError): + encoding: str + object: str + start: int + end: int + reason: str + def __init__(self, __encoding: str, __object: str, __start: int, __end: int, __reason: str) -> None: ... + +class UnicodeTranslateError(UnicodeError): ... +class Warning(Exception): ... +class UserWarning(Warning): ... +class DeprecationWarning(Warning): ... +class SyntaxWarning(Warning): ... +class RuntimeWarning(Warning): ... +class FutureWarning(Warning): ... +class PendingDeprecationWarning(Warning): ... +class ImportWarning(Warning): ... +class UnicodeWarning(Warning): ... +class BytesWarning(Warning): ... +class ResourceWarning(Warning): ... + +if sys.version_info >= (3, 10): + class EncodingWarning(Warning): ... diff --git a/typeshed/stdlib/collections/__init__.pyi b/typeshed/stdlib/collections/__init__.pyi new file mode 100644 index 0000000..8815a4b --- /dev/null +++ b/typeshed/stdlib/collections/__init__.pyi @@ -0,0 +1,60 @@ +import sys +from typing import ( + Any, + Dict, + Generic, + ItemsView, + Iterable, + Iterator, + KeysView, + Optional, + Reversible, + Tuple, + Type, + TypeVar, + Union, + ValuesView, +) + +_S = TypeVar("_S") +_T = TypeVar("_T") +_KT = TypeVar("_KT") +_VT = TypeVar("_VT") + +if sys.version_info >= (3, 7): + def namedtuple( + typename: str, + field_names: Union[str, Iterable[str]], + *, + rename: bool = ..., + module: Optional[str] = ..., + defaults: Optional[Iterable[Any]] = ..., + ) -> Type[Tuple[Any, ...]]: ... + +else: + def namedtuple( + typename: str, + field_names: Union[str, Iterable[str]], + *, + verbose: bool = ..., + rename: bool = ..., + module: Optional[str] = ..., + ) -> Type[Tuple[Any, ...]]: ... + +class _OrderedDictKeysView(KeysView[_KT], Reversible[_KT]): + def __reversed__(self) -> Iterator[_KT]: ... + +class _OrderedDictItemsView(ItemsView[_KT, _VT], Reversible[Tuple[_KT, _VT]]): + def __reversed__(self) -> Iterator[Tuple[_KT, _VT]]: ... + +class _OrderedDictValuesView(ValuesView[_VT], Reversible[_VT]): + def __reversed__(self) -> Iterator[_VT]: ... + +class OrderedDict(Dict[_KT, _VT], Reversible[_KT], Generic[_KT, _VT]): + def popitem(self, last: bool = ...) -> Tuple[_KT, _VT]: ... + def move_to_end(self, key: _KT, last: bool = ...) -> None: ... + def copy(self: _S) -> _S: ... + def __reversed__(self) -> Iterator[_KT]: ... + def keys(self) -> _OrderedDictKeysView[_KT]: ... + def items(self) -> _OrderedDictItemsView[_KT, _VT]: ... + def values(self) -> _OrderedDictValuesView[_VT]: ... diff --git a/typeshed/stdlib/errno.pyi b/typeshed/stdlib/errno.pyi new file mode 100644 index 0000000..0671ebb --- /dev/null +++ b/typeshed/stdlib/errno.pyi @@ -0,0 +1 @@ +from uerrno import * diff --git a/typeshed/stdlib/gc.pyi b/typeshed/stdlib/gc.pyi new file mode 100644 index 0000000..03e9cef --- /dev/null +++ b/typeshed/stdlib/gc.pyi @@ -0,0 +1,74 @@ +"""Control the garbage collector""" + +from typing import overload + +def enable() -> None: + """Enable automatic garbage collection.""" + ... + +def disable() -> None: + """Disable automatic garbage collection. Heap memory can still be allocated, + and garbage collection can still be initiated manually using :meth:`gc.collect`.""" + +def collect() -> None: + """Run a garbage collection.""" + ... + +def mem_alloc() -> int: + """Return the number of bytes of heap RAM that are allocated. + + .. admonition:: Difference to CPython + :class: attention + + This function is MicroPython extension. + """ + ... + +def mem_free() -> int: + """Return the number of bytes of available heap RAM, or -1 if this amount + is not known. + + .. admonition:: Difference to CPython + :class: attention + + This function is MicroPython extension. + """ + ... + +@overload +def threshold() -> int: + """Query the additional GC allocation threshold. + + .. admonition:: Difference to CPython + :class: attention + + This function is a MicroPython extension. CPython has a similar + function - ``set_threshold()``, but due to different GC + implementations, its signature and semantics are different. + """ + ... + +@overload +def threshold(amount: int) -> None: + """Set the additional GC allocation threshold. Normally, a collection + is triggered only when a new allocation cannot be satisfied, i.e. on an + out-of-memory (OOM) condition. If this function is called, in addition to + OOM, a collection will be triggered each time after *amount* bytes have been + allocated (in total, since the previous time such an amount of bytes + have been allocated). *amount* is usually specified as less than the + full heap size, with the intention to trigger a collection earlier than when the + heap becomes exhausted, and in the hope that an early collection will prevent + excessive memory fragmentation. This is a heuristic measure, the effect + of which will vary from application to application, as well as + the optimal value of the *amount* parameter. + + A value of -1 means a disabled allocation threshold. + + .. admonition:: Difference to CPython + :class: attention + + This function is a MicroPython extension. CPython has a similar + function - ``set_threshold()``, but due to different GC + implementations, its signature and semantics are different. + """ + ... diff --git a/typeshed/stdlib/love.pyi b/typeshed/stdlib/love.pyi new file mode 100644 index 0000000..9018624 --- /dev/null +++ b/typeshed/stdlib/love.pyi @@ -0,0 +1 @@ +def badaboom() -> None: ... diff --git a/typeshed/stdlib/machine.pyi b/typeshed/stdlib/machine.pyi new file mode 100644 index 0000000..aad458c --- /dev/null +++ b/typeshed/stdlib/machine.pyi @@ -0,0 +1,56 @@ +"""The machine module contains specific functions related to the micro:bit +hardware. Most functions in this module allow to achieve direct and +unrestricted access to and control of hardware blocks on a system (like CPU, +timers, buses, etc.). Used incorrectly, this can lead to malfunction, lockups, +crashes of your board, and in extreme cases, hardware damage. +""" +from .microbit import MicroBitDigitalPin + +def unique_id() -> bytes: + """Returns a byte string with a unique identifier of a board. It will vary + from one board instance to another. + """ + ... + +def reset() -> None: + """Resets the device in a manner similar to pushing the external RESET button.""" + ... + +def freq() -> int: + """Returns CPU frequency in hertz.""" + ... + +def disable_irq() -> None: + """Disable interrupt requests. Returns the previous IRQ state which should be + considered an opaque value. This return value should be passed to the + :func:`machine.enable_irq()` function to restore interrupts to their + original state, before :func:`machine.disable_irq()` was called. + """ + ... + +def enable_irq() -> None: + """Re-enable interrupt requests. The *state* parameter should be the value + that was returned from the most recent call to the + :func:`machine.disable_irq()` function. + """ + ... + +def time_pulse_us( + pin: MicroBitDigitalPin, pulse_level: int, timeout_us: int = 1000000 +) -> int: + """Time a pulse on the given *pin*, and return the duration of the pulse in + microseconds. The *pulse_level* argument should be 0 to time a low pulse or + 1 to time a high pulse. + + If the current input value of the pin is different to *pulse_level*, the + function first (*) waits until the pin input becomes equal to + *pulse_level*, then (**) times the duration that the pin is equal to + *pulse_level*. If the pin is already equal to *pulse_level* then timing + starts straight away. + + The function will return -2 if there was timeout waiting for condition + marked (*) above, and -1 if there was timeout during the main measurement, + marked (**) above. The timeout is the same for both cases and given by + *timeout_us* (which is in microseconds). + """ + ... diff --git a/typeshed/stdlib/math.pyi b/typeshed/stdlib/math.pyi new file mode 100644 index 0000000..614cc93 --- /dev/null +++ b/typeshed/stdlib/math.pyi @@ -0,0 +1,117 @@ +"""The ``math`` module provides some basic mathematical functions for +working with floating-point numbers. +""" + +from typing import Tuple + +def acos(x: float) -> float: + """Return the inverse cosine of ``x``.""" + ... + +def asin(x: float) -> float: + """Return the inverse sine of ``x``.""" + ... + +def atan(x: float) -> float: + """Return the inverse tangent of ``x``.""" + ... + +def atan2(y: float, x: float) -> float: + """Return the principal value of the inverse tangent of ``y/x``.""" + ... + +def ceil(x: float) -> int: + """Return an integer, being ``x`` rounded towards positive infinity.""" + ... + +def copysign(x: float, y: float) -> float: + """Return ``x`` with the sign of ``y``.""" + ... + +def cos(x: float) -> float: + """Return the cosine of ``x``.""" + ... + +def degrees(x: float) -> float: + """Return radians ``x`` converted to degrees.""" + ... + +def exp(x: float) -> float: + """Return the exponential of ``x``.""" + ... + +def fabs(x: float) -> float: + """Return the absolute value of ``x``.""" + ... + +def floor(x: float) -> int: + """Return an integer, being ``x`` rounded towards negative infinity.""" + ... + +def fmod(x: float, y: float) -> float: + """Return the remainder of ``x/y``.""" + ... + +def frexp(x: float) -> Tuple[float, int]: + """Decomposes a floating-point number into its mantissa and exponent. + The returned value is the tuple ``(m, e)`` such that ``x == m * 2**e`` + exactly. If ``x == 0`` then the function returns ``(0.0, 0)``, otherwise + the relation ``0.5 <= abs(m) < 1`` holds. + """ + ... + +def isfinite(x: float) -> bool: + """Return ``True`` if ``x`` is finite.""" + ... + +def isinf(x: float) -> bool: + """Return ``True`` if ``x`` is infinite.""" + ... + +def isnan(x: float) -> bool: + """Return ``True`` if ``x`` is not-a-number""" + ... + +def ldexp(x: float, i: int) -> float: + """Return ``x * (2**exp)``.""" + ... + +def log(x: float) -> float: + """Return the natural logarithm of ``x``.""" + ... + +def modf(x: float) -> Tuple[float, float]: + """Return a tuple of two floats, being the fractional and integral parts of + ``x``. Both return values have the same sign as ``x``. + """ + ... + +def pow(x: float, y: float) -> float: + """Returns ``x`` to the power of ``y``.""" + ... + +def radians(x: float) -> float: + """Return degrees ``x`` converted to radians.""" + ... + +def sin(x: float) -> float: + """Return the sine of ``x``.""" + ... + +def sqrt(x: float) -> float: + """Return the square root of ``x``.""" + ... + +def tan(x: float) -> float: + """Return the tangent of ``x``.""" + ... + +def trunc(x: float) -> int: + """Return an integer, being ``x`` rounded towards 0.""" + ... + +e: float +"""base of the natural logarithm""" + +pi: float +"""the ratio of a circle's circumference to its diameter""" diff --git a/typeshed/stdlib/microbit/__init__.pyi b/typeshed/stdlib/microbit/__init__.pyi new file mode 100644 index 0000000..3478af2 --- /dev/null +++ b/typeshed/stdlib/microbit/__init__.pyi @@ -0,0 +1,449 @@ +"""The ``microbit`` module gives you access to all the hardware that is built-in +into your board. +""" + +from typing import Any, List, overload + +from . import accelerometer as accelerometer +from . import compass as compass +from . import display as display +from . import i2c as i2c +from . import microphone as microphone +from . import speaker as speaker +from . import spi as spi +from . import uart as uart + +# V2 only +from .. import audio as audio + +def panic(n: int) -> None: + """Enter a panic mode. Requires restart. Pass in an arbitrary integer <= 255 + to indicate a status:: + + microbit.panic(255) + """ + +def reset() -> None: + """Restart the board.""" + +def sleep(n: float) -> None: + """Wait for ``n`` milliseconds. One second is 1000 milliseconds, so:: + + microbit.sleep(1000) + + will pause the execution for one second. ``n`` can be an integer or + a floating point number. + """ + +def running_time() -> int: + """Return the number of milliseconds since the board was switched on or + restarted. + """ + +def temperature() -> int: + """Return the temperature of the micro:bit in degrees Celcius.""" + +def set_volume(v: int) -> None: + """Sets the volume. ``v`` is a value between 0 and 255. + + **V2** only. + + Out of range values will be clamped to 0 or 255. + """ + ... + +class Button: + """Represents a button. + + .. note:: + This class is not actually available to the user, it is only used by + the two button instances, which are provided already initialized. + """ + + def is_pressed(self) -> bool: + """Returns ``True`` if the specified button ``button`` is pressed, and + ``False`` otherwise. + """ + ... + def was_pressed(self) -> bool: + """Returns ``True`` or ``False`` to indicate if the button was pressed + since the device started or the last time this method was called. + + Calling this method will clear the press state so + that the button must be pressed again before this method will return + ``True`` again. + """ + ... + def get_presses(self) -> int: + """Returns the running total of button presses, and resets this total + to zero before returning. + """ + ... + +button_a: Button +"""A ``Button`` instance representing the left button.""" + +button_b: Button +"""Represents the right button.""" + +class MicroBitDigitalPin: + """The pins are your board's way to communicate with external devices connected to + it. There are 19 pins for your disposal, numbered 0-16 and 19-20. Pins 17 and + 18 are not available. There is also a ``pin_logo`` **V2** and ``pin_speaker`` + **V2** available to use with the latest micro:bit device. + """ + + NO_PULL: int + PULL_UP: int + PULL_DOWN: int + def read_digital(self) -> int: + """Return 1 if the pin is high, and 0 if it's low.""" + ... + def write_digital(self, value: int) -> None: + """Set the pin to high if ``value`` is 1, or to low, if it is 0.""" + ... + def set_pull(self, value: int) -> None: + """Set the pull state to one of three possible values: ``pin.PULL_UP``, + ``pin.PULL_DOWN`` or ``pin.NO_PULL`` (where ``pin`` is an instance of + a pin). See below for discussion of default pull states. + """ + ... + def get_pull(self) -> int: + """Returns the pull configuration on a pin, which can be one of three + possible values: ``NO_PULL``, ``PULL_DOWN``, or ``PULL_UP``. These + are set using the ``set_pull()`` method or automatically configured + when a pin mode requires it.""" + ... + def get_mode(self) -> str: + """Returns the pin mode. When a pin is used for a specific function, like + writing a digital value, or reading an analog value, the pin mode + changes. Pins can have one of the following modes: ``"unused"``, + ``"analog"``, ``"read_digital"``, ``"write_digital"``, + ``"display"``, ``"button"``, ``"music"``, ``"audio"``, + ``"touch"``, ``"i2c"``, ``"spi"``. + """ + ... + +class MicroBitAnalogDigitalPin(MicroBitDigitalPin): + def read_analog(self) -> int: + """Read the voltage applied to the pin, and return it as an integer + between 0 (meaning 0V) and 1023 (meaning 3.3V). + """ + def write_analog(self, value: int) -> None: + """Output a PWM signal on the pin, with the duty cycle proportional to + the provided ``value``. The ``value`` may be either an integer or a + floating point number between 0 (0% duty cycle) and 1023 (100% duty). + """ + def set_analog_period(self, period: int) -> None: + """Set the period of the PWM signal being output to ``period`` in + milliseconds. The minimum valid value is 1ms. + """ + def set_analog_period_microseconds(self, period: int) -> None: + """Set the period of the PWM signal being output to ``period`` in + microseconds. The minimum valid value is 256µs. + """ + +class MicroBitTouchPin(MicroBitAnalogDigitalPin): + CAPACITIVE: int + RESISTIVE: int + def is_touched(self) -> bool: + """Return ``True`` if the pin is being touched with a finger, otherwise + return ``False``. + + .. note:: + The default touch mode for the pins on the edge connector is + `resistive`. The default for the logo pin **V2** is `capacitive`. + + **Resistive touch** + This test is done by measuring how much resistance there is between the + pin and ground. A low resistance gives a reading of ``True``. To get + a reliable reading using a finger you may need to touch the ground pin + with another part of your body, for example your other hand. + + **Capacitive touch** + This test is done by interacting with the electric field of a capacitor + using a finger as a conductor. `Capacitive touch + `_ + does not require you to make a ground connection as part of a circuit. + """ + ... + def set_touch_mode(value: int) -> None: + """ + .. note:: + The default touch mode for the pins on the edge connector is + `resistive`. The default for the logo pin **V2** is `capacitive`. + + Set the touch mode for the given pin. Value can be either ``CAPACITIVE`` + or ``RESISTIVE``. For example, ``pin0.set_touch_mode(pin0.CAPACITIVE)``. + """ + ... + +pin0: MicroBitTouchPin +pin1: MicroBitTouchPin +pin2: MicroBitTouchPin +pin3: MicroBitAnalogDigitalPin +pin4: MicroBitAnalogDigitalPin +pin5: MicroBitDigitalPin +pin6: MicroBitDigitalPin +pin7: MicroBitDigitalPin +pin8: MicroBitDigitalPin +pin9: MicroBitDigitalPin +pin10: MicroBitAnalogDigitalPin +pin11: MicroBitDigitalPin +pin12: MicroBitDigitalPin +pin13: MicroBitDigitalPin +pin14: MicroBitDigitalPin +pin15: MicroBitDigitalPin +pin16: MicroBitDigitalPin +pin19: MicroBitDigitalPin +pin20: MicroBitDigitalPin + +pin_logo: MicroBitTouchPin +pin_speaker: MicroBitAnalogDigitalPin + +class Image: + """The ``Image`` class is used to create images that can be displayed easily on + the device's LED matrix. Given an image object it's possible to display it via + the ``display`` API:: + + display.show(Image.HAPPY) + """ + + HEART: Image + HEART_SMALL: Image + HAPPY: Image + SMILE: Image + SAD: Image + CONFUSED: Image + ANGRY: Image + ASLEEP: Image + SURPRISED: Image + SILLY: Image + FABULOUS: Image + MEH: Image + YES: Image + NO: Image + CLOCK12: Image + CLOCK11: Image + CLOCK10: Image + CLOCK9: Image + CLOCK8: Image + CLOCK7: Image + CLOCK6: Image + CLOCK5: Image + CLOCK4: Image + CLOCK3: Image + CLOCK2: Image + CLOCK1: Image + ARROW_N: Image + ARROW_NE: Image + ARROW_E: Image + ARROW_SE: Image + ARROW_S: Image + ARROW_SW: Image + ARROW_W: Image + ARROW_NW: Image + TRIANGLE: Image + TRIANGLE_LEFT: Image + CHESSBOARD: Image + DIAMOND: Image + DIAMOND_SMALL: Image + SQUARE: Image + SQUARE_SMALL: Image + RABBIT: Image + COW: Image + MUSIC_CROTCHET: Image + MUSIC_QUAVER: Image + MUSIC_QUAVERS: Image + PITCHFORK: Image + XMAS: Image + PACMAN: Image + TARGET: Image + TSHIRT: Image + ROLLERSKATE: Image + DUCK: Image + HOUSE: Image + TORTOISE: Image + BUTTERFLY: Image + STICKFIGURE: Image + GHOST: Image + SWORD: Image + GIRAFFE: Image + SKULL: Image + UMBRELLA: Image + SNAKE: Image + + ALL_CLOCKS: List[Image] + ALL_ARROWS: List[Image] + @overload + def __init__(self, string: str) -> None: + """``string`` has to consist of digits 0-9 arranged into lines, + describing the image, for example:: + + image = Image("90009:" + "09090:" + "00900:" + "09090:" + "90009") + + will create a 5×5 image of an X. The end of a line is indicated by a + colon. It's also possible to use a newline (\n) to indicate the end of + a line like this:: + + image = Image("90009\n" + "09090\n" + "00900\n" + "09090\n" + "90009") + """ + ... + @overload + def __init__( + self, width: int = None, height: int = None, buffer: Any = None + ) -> None: + """Create an empty image with ``width`` columns and ``height`` rows. + Optionally ``buffer`` can be an array of ``width``×``height`` integers + in range 0-9 to initialize the image:: + + Image(2, 2, b'\x08\x08\x08\x08') + + or:: + + Image(2, 2, bytearray([9,9,9,9])) + + Will create a 2 x 2 pixel image at full brightness. + + .. note:: + + Keyword arguments cannot be passed to ``buffer``. + """ + ... + def width(self) -> int: + """Return the number of columns in the image.""" + ... + def height(self) -> int: + """Return the numbers of rows in the image.""" + ... + def set_pixel(self, x: int, y: int, value: int) -> None: + """Set the brightness of the pixel at column ``x`` and row ``y`` to the + ``value``, which has to be between 0 (dark) and 9 (bright). + + This method will raise an exception when called on any of the built-in + read-only images, like ``Image.HEART``. + """ + ... + def get_pixel(self, x: int, y: int) -> int: + """Return the brightness of pixel at column ``x`` and row ``y`` as an + integer between 0 and 9. + """ + ... + def shift_left(self, n: int) -> Image: + """Return a new image created by shifting the picture left by ``n`` + columns. + """ + ... + def shift_right(self, n: int) -> Image: + """Same as ``image.shift_left(-n)``.""" + ... + def shift_up(self, n: int) -> Image: + """Return a new image created by shifting the picture up by ``n`` + rows. + """ + ... + def shift_down(self, n: int) -> Image: + """Same as ``image.shift_up(-n)``.""" + ... + def crop(self, x: int, y: int, w: int, h: int) -> Image: + """Return a new image by cropping the picture to a width of ``w`` and a + height of ``h``, starting with the pixel at column ``x`` and row + ``y``. + """ + ... + def copy(self) -> Image: + """Return an exact copy of the image.""" + ... + def invert(self) -> Image: + """Return a new image by inverting the brightness of the pixels in the + source image.""" + ... + def fill(self, value: int) -> None: + """Set the brightness of all the pixels in the image to the + ``value``, which has to be between 0 (dark) and 9 (bright). + + This method will raise an exception when called on any of the built-in + read-only images, like ``Image.HEART``. + """ + ... + def blit( + self, + src: Image, + x: int, + y: int, + w: int, + h: int, + xdest: int = ..., + ydest: int = ..., + ) -> None: + """Copy the rectangle defined by ``x``, ``y``, ``w``, ``h`` from the + image ``src`` into this image at ``xdest``, ``ydest``. Areas in the + source rectangle, but outside the source image are treated as having a + value of 0. + + ``shift_left()``, ``shift_right()``, ``shift_up()``, ``shift_down()`` + and ``crop()`` can are all implemented by using ``blit()``. + + For example, img.crop(x, y, w, h) can be implemented as:: + + def crop(self, x, y, w, h): + res = Image(w, h) + res.blit(self, x, y, w, h) + return res + """ + ... + def __repr__(self) -> str: + """Get a compact string representation of the image.""" + ... + def __str__(self) -> str: + """Get a readable string representation of the image.""" + ... + def __add__(self, other: Image) -> Image: + """Create a new image by adding the brightness values from the two + images for each pixel. + """ + ... + def __sub__(self, other: Image) -> Image: + """Create a new image by subtracting the brightness values of the + other image from this image. + """ + ... + def __mul__(self, n: float) -> Image: + """Create a new image by multiplying the brightness of each pixel by + ``n``. + """ + ... + def __div__(self, other: float) -> Image: + """Create a new image by multiplying the brightness of each pixel by + ``n``. + """ + ... + +class SoundEvent: + """Represents the transition of sound events, from ``loud`` to ``quiet`` like speaking or background music.""" + + LOUD: SoundEvent + """Represents the transition of sound events, from ``quiet`` to ``loud`` like clapping or shouting.""" + QUIET: SoundEvent + +class Sound: + """The built-in sounds can be called using ``audio.play(Sound.NAME)``.""" + + GIGGLE: Sound + HAPPY: Sound + HELLO: Sound + MYSTERIOUS: Sound + SAD: Sound + SLIDE: Sound + SOARING: Sound + SPRING: Sound + TWINKLE: Sound + YAWN: Sound diff --git a/typeshed/stdlib/microbit/accelerometer.pyi b/typeshed/stdlib/microbit/accelerometer.pyi new file mode 100644 index 0000000..39bd144 --- /dev/null +++ b/typeshed/stdlib/microbit/accelerometer.pyi @@ -0,0 +1,77 @@ +"""This object gives you access to the on-board accelerometer. The accelerometer +also provides convenience functions for detecting gestures. The +recognised gestures are: ``up``, ``down``, ``left``, ``right``, ``face up``, +``face down``, ``freefall``, ``3g``, ``6g``, ``8g``, ``shake``. + +By default MicroPython sets the accelerometer range to +/- 2g, changing the +accelerometer range is currently not possible in MicroPython. +The accelerometer returns a value in the range 0..1024 for each axis, which is +then scaled accordingly. +""" + +from typing import Tuple + +def get_x() -> int: + """Get the acceleration measurement in the ``x`` axis, as a positive or + negative integer, depending on the direction. The measurement is given in + milli-g. By default the accelerometer is configured with a range of +/- 2g, + and so this method will return within the range of +/- 2000mg. + """ + ... + +def get_y() -> int: + """Get the acceleration measurement in the ``y`` axis, as a positive or + negative integer, depending on the direction. The measurement is given in + milli-g. By default the accelerometer is configured with a range of +/- 2g, + and so this method will return within the range of +/- 2000mg. + """ + ... + +def get_z() -> int: + """Get the acceleration measurement in the ``z`` axis, as a positive or + negative integer, depending on the direction. The measurement is given in + milli-g. By default the accelerometer is configured with a range of +/- 2g, + and so this method will return within the range of +/- 2000mg. + """ + ... + +def get_values() -> Tuple[int, int, int]: + """Get the acceleration measurements in all axes at once, as a three-element + tuple of integers ordered as X, Y, Z. + By default the accelerometer is configured with a range of +/- 2g, and so + X, Y, and Z will be within the range of +/-2000mg. + """ + ... + +def current_gesture() -> str: + """Return the name of the current gesture. + + .. note:: + + MicroPython understands the following gesture names: ``"up"``, ``"down"``, + ``"left"``, ``"right"``, ``"face up"``, ``"face down"``, ``"freefall"``, + ``"3g"``, ``"6g"``, ``"8g"``, ``"shake"``. Gestures are always + represented as strings. + """ + ... + +def is_gesture(name: str) -> bool: + """Return True or False to indicate if the named gesture is currently active.""" + ... + +def was_gesture(name: str) -> bool: + """Return True or False to indicate if the named gesture was active since the + last call. + """ + +def get_gestures() -> Tuple[str, ...]: + """Return a tuple of the gesture history. The most recent is listed last. + Also clears the gesture history before returning. + + .. note:: + + Gestures are not updated in the background so there needs to be constant + calls to some accelerometer method to do the gesture detection. Usually + gestures can be detected using a loop with a small :func:`microbit.sleep` delay. + """ + ... diff --git a/typeshed/stdlib/microbit/compass.pyi b/typeshed/stdlib/microbit/compass.pyi new file mode 100644 index 0000000..d1a7cb3 --- /dev/null +++ b/typeshed/stdlib/microbit/compass.pyi @@ -0,0 +1,59 @@ +"""This module lets you access the built-in electronic compass. Before using, +the compass should be calibrated, otherwise the readings may be wrong. + +.. warning:: + + Calibrating the compass will cause your program to pause until calibration + is complete. Calibration consists of a little game to draw a circle on the + LED display by rotating the device. +""" + +def calibrate() -> None: + """Starts the calibration process. An instructive message will be scrolled + to the user after which they will need to rotate the device in order to + draw a circle on the LED display. + """ + ... + +def is_calibrated() -> bool: + """Returns ``True`` if the compass has been successfully calibrated, and + returns ``False`` otherwise. + """ + ... + +def clear_calibration() -> None: + """Undoes the calibration, making the compass uncalibrated again.""" + ... + +def get_x() -> int: + """Gives the reading of the magnetic field strength on the ``x`` axis in nano + tesla, as a positive or negative integer, depending on the direction of the + field. + """ + ... + +def get_y() -> int: + """Gives the reading of the magnetic field strength on the ``y`` axis in nano + tesla, as a positive or negative integer, depending on the direction of the + field. + """ + ... + +def get_z() -> int: + """Gives the reading of the magnetic field strength on the ``z`` axis in nano + tesla, as a positive or negative integer, depending on the direction of the + field. + """ + ... + +def heading() -> int: + """Gives the compass heading, calculated from the above readings, as an + integer in the range from 0 to 360, representing the angle in degrees, + clockwise, with north as 0. + """ + ... + +def get_field_strength() -> int: + """Returns an integer indication of the magnitude of the magnetic field around + the device in nano tesla.""" + ... diff --git a/typeshed/stdlib/microbit/display.pyi b/typeshed/stdlib/microbit/display.pyi new file mode 100644 index 0000000..05ba416 --- /dev/null +++ b/typeshed/stdlib/microbit/display.pyi @@ -0,0 +1,103 @@ +"""This module controls the 5×5 LED display on the front of your board. It can +be used to display images, animations and even text. +""" + +from . import Image +from typing import Union, overload, Iterable + +def get_pixel(x: int, y: int) -> int: + """Return the brightness of the LED at column ``x`` and row ``y`` as an + integer between 0 (off) and 9 (bright). + """ + ... + +def set_pixel(x: int, y: int, value: int) -> None: + """Set the brightness of the LED at column ``x`` and row ``y`` to ``value``, + which has to be an integer between 0 and 9. + """ + ... + +def clear() -> None: + """Set the brightness of all LEDs to 0 (off).""" + ... + +@overload +def show(image: Image) -> None: + """Display the ``image``.""" + ... + +@overload +def show( + iterable: Union[str, float, int, Iterable[Image]], + delay: int = 400, + wait: bool = True, + loop: bool = False, + clear: bool = False, +) -> None: + """If ``value`` is a string, float or integer, display letters/digits in sequence. + Otherwise, if ``value`` is an iterable sequence of images, display these images in sequence. + Each letter, digit or image is shown with ``delay`` milliseconds between them. + + If ``wait`` is ``True``, this function will block until the animation is + finished, otherwise the animation will happen in the background. + + If ``loop`` is ``True``, the animation will repeat forever. + + If ``clear`` is ``True``, the display will be cleared after the iterable has finished. + + Note that the ``wait``, ``loop`` and ``clear`` arguments must be specified + using their keyword. + + .. note:: + + If using a generator as the ``iterable``, then take care not to allocate any memory + in the generator as allocating memory in an interrupt is prohibited and will raise a + ``MemoryError``. + """ + ... + +def scroll( + string: Union[str, float, int], + delay: int = 150, + wait: bool = True, + loop: bool = False, + monospace: bool = False, +) -> None: + """Scrolls ``value`` horizontally on the display. If ``value`` is an integer or float it is + first converted to a string using ``str()``. The ``delay`` parameter controls how fast + the text is scrolling. + + If ``wait`` is ``True``, this function will block until the animation is + finished, otherwise the animation will happen in the background. + + If ``loop`` is ``True``, the animation will repeat forever. + + If ``monospace`` is ``True``, the characters will all take up 5 pixel-columns + in width, otherwise there will be exactly 1 blank pixel-column between each + character as they scroll. + + Note that the ``wait``, ``loop`` and ``monospace`` arguments must be specified + using their keyword. + """ + ... + +def on() -> None: + """Use on() to turn on the display.""" + ... + +def off() -> None: + """Use off() to turn off the display (thus allowing you to re-use the GPIO + pins associated with the display for other purposes). + """ + ... + +def is_on() -> bool: + """Returns ``True`` if the display is on, otherwise returns ``False``.""" + ... + +def read_light_level(): + """Use the display's LEDs in reverse-bias mode to sense the amount of light + falling on the display. Returns an integer between 0 and 255 representing + the light level, with larger meaning more light. + """ + ... diff --git a/typeshed/stdlib/microbit/i2c.pyi b/typeshed/stdlib/microbit/i2c.pyi new file mode 100644 index 0000000..44a509c --- /dev/null +++ b/typeshed/stdlib/microbit/i2c.pyi @@ -0,0 +1,52 @@ +"""The ``i2c`` module lets you communicate with devices connected to your board +using the I²C bus protocol. There can be multiple slave devices connected at +the same time, and each one has its own unique address, that is either fixed +for the device or configured on it. Your board acts as the I²C master. + +We use 7-bit addressing for devices because of the reasons stated +`here `_. + +This may be different to other micro:bit related solutions. + +How exactly you should communicate with the devices, that is, what bytes to +send and how to interpret the responses, depends on the device in question and +should be described separately in that device's documentation. +""" + +from . import MicroBitDigitalPin, pin19, pin20 +from typing import List, Union +from . import pin19, pin20 + +def init( + freq: int = 100000, sda: MicroBitDigitalPin = pin20, scl: MicroBitDigitalPin = pin19 +) -> None: + """Re-initialize peripheral with the specified clock frequency ``freq`` on the + specified ``sda`` and ``scl`` pins. + + .. warning:: + + On a micro:bit V1 board, changing the I²C pins from defaults will make + the accelerometer and compass stop working, as they are connected + internally to those pins. This warning does not apply to the **V2** + revision of the micro:bit as this has `separate I²C lines + `_ + for the motion sensors and the edge connector. + """ + ... + +def scan() -> List[int]: + """Scan the bus for devices. Returns a list of 7-bit addresses corresponding + to those devices that responded to the scan.""" + ... + +def read(addr: int, n: int, repeat: bool = False) -> bytes: + """Read ``n`` bytes from the device with 7-bit address ``addr``. If ``repeat`` + is ``True``, no stop bit will be sent. + """ + ... + +def write(addr: int, buf: Union[bytes, bytearray], repeat=False) -> None: + """Write bytes from ``buf`` to the device with 7-bit address ``addr``. If + ``repeat`` is ``True``, no stop bit will be sent. + """ + ... diff --git a/typeshed/stdlib/microbit/microphone.pyi b/typeshed/stdlib/microbit/microphone.pyi new file mode 100644 index 0000000..cf1a69f --- /dev/null +++ b/typeshed/stdlib/microbit/microphone.pyi @@ -0,0 +1,59 @@ +"""This object lets you access the built-in microphone available on the +micro:bit **V2**. It can be used to respond to sound. The microphone input +is located on the front of the board alongside a microphone activity LED, +which is lit when the microphone is in use. +""" + +from typing import Optional, Tuple +from . import SoundEvent + +def current_event() -> Optional[SoundEvent]: + """ + * **return**: the name of the last recorded sound event, + ``SoundEvent('loud')`` or ``SoundEvent('quiet')``. + """ + ... + +def was_event(event: SoundEvent) -> bool: + """ + * **event**: a sound event, such as ``SoundEvent.LOUD`` or + ``SoundEvent.QUIET``. + * **return**: ``true`` if sound was heard at least once since the last + call, otherwise ``false``. ``was_event()`` also clears the sound + event history before returning. + """ + ... + +def is_event(event): + """ + * **event**: a sound event, such as ``SoundEvent.LOUD`` or + ``SoundEvent.QUIET``. + * **return**: ``true`` if sound event is the most recent since the last + call, otherwise ``false``. It does not clear the sound event history. + """ + ... + +def get_events() -> Tuple[SoundEvent, ...]: + """ + * **return**: a tuple of the event history. The most recent is listed last. + ``get_events()`` also clears the sound event history before returning. + """ + ... + +def set_threshold(event: SoundEvent, value: int) -> None: + """ + * **event**: a sound event, such as ``SoundEvent.LOUD`` or + ``SoundEvent.QUIET``. + + * **value**: The threshold level in the range 0-255. For example, + ``set_threshold(SoundEvent.LOUD, 250)`` will only trigger if the sound is + very loud (>= 250). + """ + ... + +def sound_level() -> int: + """ + * **return**: a representation of the sound pressure level in the range 0 to + 255. + """ + ... diff --git a/typeshed/stdlib/microbit/speaker.pyi b/typeshed/stdlib/microbit/speaker.pyi new file mode 100644 index 0000000..b2126fc --- /dev/null +++ b/typeshed/stdlib/microbit/speaker.pyi @@ -0,0 +1,18 @@ +"""The micro:bit **V2** has a built-in speaker located on the rear of the board. + +By default sound output will be via the edge connector on pin 0 and the +built-in speaker **V2**. You can connect wired headphones or a speaker to +pin 0 and GND on the edge connector to hear the sounds. + +The speaker can be turned off or on using the functions listed here. +""" + +def off() -> None: + """Use ``off()`` to turn off the speaker. This does not disable sound output + to an edge connector pin. + """ + ... + +def on() -> None: + """Use ``on()`` to turn on the speaker.""" + ... diff --git a/typeshed/stdlib/microbit/spi.pyi b/typeshed/stdlib/microbit/spi.pyi new file mode 100644 index 0000000..1705b53 --- /dev/null +++ b/typeshed/stdlib/microbit/spi.pyi @@ -0,0 +1,70 @@ +"""The ``spi`` module lets you talk to a device connected to your board using +a serial peripheral interface (SPI) bus. SPI uses a so-called master-slave +architecture with a single master. You will need to specify the connections +for three signals: + +* SCLK : Serial Clock (output from master). +* MOSI : Master Output, Slave Input (output from master). +* MISO : Master Input, Slave Output (output from slave). +""" + + +from . import pin13, pin14, pin15, MicroBitDigitalPin +from typing import Union + + +def init(baudrate: int = 1000000, bits: int = 8, mode: int = 0, + sclk: MicroBitDigitalPin = pin13, + mosi: MicroBitDigitalPin = pin15, + miso: MicroBitDigitalPin = pin14) -> None: + """Initialize SPI communication with the specified parameters on the + specified ``pins``. Note that for correct communication, the parameters + have to be the same on both communicating devices. + + The ``baudrate`` defines the speed of communication. + + The ``bits`` defines the size of bytes being transmitted. Currently only + ``bits=8`` is supported. However, this may change in the future. + + The ``mode`` determines the combination of clock polarity and phase + according to the following convention, with polarity as the high order bit + and phase as the low order bit: + + +----------+-----------------+--------------+ + | SPI Mode | Polarity (CPOL) | Phase (CPHA) | + +==========+=================+==============+ + | 0 | 0 | 0 | + +----------+-----------------+--------------+ + | 1 | 0 | 1 | + +----------+-----------------+--------------+ + | 2 | 1 | 0 | + +----------+-----------------+--------------+ + | 3 | 1 | 1 | + +----------+-----------------+--------------+ + + Polarity (aka CPOL) 0 means that the clock is at logic value 0 when idle + and goes high (logic value 1) when active; polarity 1 means the clock is + at logic value 1 when idle and goes low (logic value 0) when active. Phase + (aka CPHA) 0 means that data is sampled on the leading edge of the clock, + and 1 means on the trailing edge + (viz. https://en.wikipedia.org/wiki/Signal_edge). + + The ``sclk``, ``mosi`` and ``miso`` arguments specify the pins to use for + each type of signal. + """ + ... + +def read(nbytes: int) -> bytes: + """Read at most ``nbytes``. Returns what was read.""" + ... + +def write(buffer: Union[bytes, bytearray]) -> None: + """Write the ``buffer`` of bytes to the bus.""" + ... + + +def write_readinto(out: Union[bytes, bytearray], in_: bytearray) -> None: + """Write the ``out`` buffer to the bus and read any response into the ``in`` + buffer. The length of the buffers should be the same. The buffers can be + the same object.""" + ... \ No newline at end of file diff --git a/typeshed/stdlib/microbit/uart.pyi b/typeshed/stdlib/microbit/uart.pyi new file mode 100644 index 0000000..acdf11a --- /dev/null +++ b/typeshed/stdlib/microbit/uart.pyi @@ -0,0 +1,129 @@ +"""The ``uart`` module lets you talk to a device connected to your board using +a serial interface. +""" + +from . import MicroBitDigitalPin +from typing import Optional, Union + +ODD: int +"""Odd partity""" + +EVEN: int +"""Even parity""" + +def init( + baudrate: int = 9600, + bits: int = 8, + parity: Optional[int] = None, + stop: int = 1, + tx: MicroBitDigitalPin = None, + rx: MicroBitDigitalPin = None, +) -> None: + """Initialize serial communication with the specified parameters on the + specified ``tx`` and ``rx`` pins. Note that for correct communication, the parameters + have to be the same on both communicating devices. + + .. warning:: + + Initializing the UART on external pins will cause the Python console on + USB to become unaccessible, as it uses the same hardware. To bring the + console back you must reinitialize the UART without passing anything for + ``tx`` or ``rx`` (or passing ``None`` to these arguments). This means + that calling ``uart.init(115200)`` is enough to restore the Python console. + + The ``baudrate`` defines the speed of communication. Common baud + rates include: + + * 9600 + * 14400 + * 19200 + * 28800 + * 38400 + * 57600 + * 115200 + + The ``bits`` defines the size of bytes being transmitted, and the board + only supports 8. The ``parity`` parameter defines how parity is checked, + and it can be ``None``, ``microbit.uart.ODD`` or ``microbit.uart.EVEN``. + The ``stop`` parameter tells the number of stop bits, and has to be 1 for + this board. + + If ``tx`` and ``rx`` are not specified then the internal USB-UART TX/RX pins + are used which connect to the USB serial converter on the micro:bit, thus + connecting the UART to your PC. You can specify any other pins you want by + passing the desired pin objects to the ``tx`` and ``rx`` parameters. + + .. note:: + + When connecting the device, make sure you "cross" the wires -- the TX + pin on your board needs to be connected with the RX pin on the device, + and the RX pin -- with the TX pin on the device. Also make sure the + ground pins of both devices are connected. + """ + ... + +def any() -> bool: + """Return ``True`` if any data is waiting, else ``False``.""" + ... + +def read(nbytes: int = None) -> bytes: + """Read bytes. If ``nbytes`` is specified then read at most that many + bytes, otherwise read as many bytes as possible. + + Return value: a bytes object or ``None`` on timeout. + + A bytes object contains a sequence of bytes. Because + `ASCII `_ characters can fit in + single bytes this type of object is often used to represent simple text + and offers methods to manipulate it as such, e.g. you can display the text + using the ``print()`` function. + + You can also convert this object into a string object, and if there are + non-ASCII characters present the encoding can be specified:: + + msg_bytes = uart.read() + msg_str = str(msg, 'UTF-8') + + .. note:: + + The timeout for all UART reads depends on the baudrate and is otherwise + not changeable via Python. The timeout, in milliseconds, is given by: + ``microbit_uart_timeout_char = 13000 / baudrate + 1`` + + .. note:: + + The internal UART RX buffer is 64 bytes, so make sure data is read + before the buffer is full or some of the data might be lost. + + .. warning:: + + Receiving ``0x03`` will stop your program by raising a Keyboard + Interrupt. You can enable or disable this using + :func:`micropython.kbd_intr()`. + """ + ... + +def readinto(buf: bytearray, nbytes: int = None) -> Optional[int]: + """Read bytes into the ``buf``. If ``nbytes`` is specified then read at most + that many bytes. Otherwise, read at most ``len(buf)`` bytes. + + Return value: number of bytes read and stored into ``buf`` or ``None`` on + timeout. + """ + +def readline() -> Optional[bytes]: + """Read a line, ending in a newline character. + + Return value: the line read or ``None`` on timeout. The newline character is + included in the returned bytes. + """ + +def write(buf: Union[bytes, bytearray]) -> Optional[int]: + """Write the buffer to the bus, it can be a bytes object or a string:: + + uart.write('hello world') + uart.write(b'hello world') + uart.write(bytes([1, 2, 3])) + + Return value: number of bytes written or ``None`` on timeout. + """ diff --git a/typeshed/stdlib/micropython.pyi b/typeshed/stdlib/micropython.pyi new file mode 100644 index 0000000..3521e40 --- /dev/null +++ b/typeshed/stdlib/micropython.pyi @@ -0,0 +1,112 @@ +"""Access and control MicroPython internals.""" + +from typing import Any, overload + +def const(expr: Any) -> Any: + """Used to declare that the expression is a constant so that the compiler can + optimise it. The use of this function should be as follows: + + .. code-block:: python + + from micropython import const + CONST_X = const(123) + CONST_Y = const(2 * CONST_X + 1) + + Constants declared this way are still accessible as global variables from + outside the module they are declared in. On the other hand, if a constant + begins with an underscore then it is hidden, it is not available as a + global variable, and does not take up any memory during execution. + """ + ... + +@overload +def opt_level() -> int: + """Returns the current optimisation level for the compilation of scripts. + + The optimisation level controls the following compilation features: + + * Assertions: at level 0 assertion statements are enabled and compiled + into the bytecode; at levels 1 and higher assertions are not compiled. + + * Built-in ``__debug__`` variable: at level 0 this variable expands to + True; at levels 1 and higher it expands to False. + + * Source-code line numbers: at levels 0, 1 and 2 source-code line number + are stored along with the bytecode so that exceptions can report the + line number they occurred at; at levels 3 and higher line numbers are + not stored. + """ + ... + +@overload +def opt_level(level: int) -> None: + """Sets the optimisation level for subsequent compilation of scripts. + + The optimisation level controls the following compilation features: + + * Assertions: at level 0 assertion statements are enabled and compiled + into the bytecode; at levels 1 and higher assertions are not compiled. + + * Built-in ``__debug__`` variable: at level 0 this variable expands to + True; at levels 1 and higher it expands to False. + + * Source-code line numbers: at levels 0, 1 and 2 source-code line number + are stored along with the bytecode so that exceptions can report the + line number they occurred at; at levels 3 and higher line numbers are + not stored. + + The default optimisation level is usually level 0. + """ + ... + +@overload +def mem_info() -> None: + """Print information about currently used memory. If the *verbose* argument + is given then extra information is printed.""" + ... + +@overload +def mem_info(verbose: Any) -> None: ... +@overload +def qstr_info() -> None: + """Print information about currently interned strings. If the *verbose* + argument is given then extra information is printed. + + The information that is printed is implementation dependent, but currently + includes the number of interned strings and the amount of RAM they use. In + verbose mode it prints out the names of all RAM-interned strings. + """ + ... + +@overload +def qstr_info(verbose: Any) -> None: ... +def stack_use() -> int: + """Return an integer representing the current amount of stack that is being + used. The absolute value of this is not particularly useful, rather it + should be used to compute differences in stack usage at different points. + """ + ... + +def heap_lock() -> None: + """Lock the heap. When locked no memory allocation can occur and a + `MemoryError` will be raised if any heap allocation is attempted. + """ + ... + +def heap_unlock() -> None: + """Unlock the heap. When locked no memory allocation can occur and a + `MemoryError` will be raised if any heap allocation is attempted. + """ + ... + +def kbd_intr(chr: int) -> None: + """Set the character that will raise a `KeyboardInterrupt` exception. By + default this is set to 3 during script execution, corresponding to Ctrl-C. + Passing -1 to this function will disable capture of Ctrl-C, and passing 3 + will restore it. + + This function can be used to prevent the capturing of Ctrl-C on the + incoming stream of characters that is usually used for the REPL, in case + that stream is used for other purposes. + """ + ... diff --git a/typeshed/stdlib/music.pyi b/typeshed/stdlib/music.pyi new file mode 100644 index 0000000..3a43783 --- /dev/null +++ b/typeshed/stdlib/music.pyi @@ -0,0 +1,123 @@ +"""This is the ``music`` module and you can use it to create and play melodies. +By default sound output will be via the edge connector on pin 0 and the +:doc:`built-in speaker ` **V2**. You can connect wired headphones or +a speaker to pin 0 and GND on the edge connector to hear the sound: +""" +from typing import Tuple, Union, List + +from .microbit import MicroBitDigitalPin, pin0 + +DADADADUM: Tuple[str, ...] +ENTERTAINER: Tuple[str, ...] +PRELUDE: Tuple[str, ...] +ODE: Tuple[str, ...] +NYAN: Tuple[str, ...] +RINGTONE: Tuple[str, ...] +FUNK: Tuple[str, ...] +BLUES: Tuple[str, ...] +BIRTHDAY: Tuple[str, ...] +WEDDING: Tuple[str, ...] +FUNERAL: Tuple[str, ...] +PUNCHLINE: Tuple[str, ...] +PYTHON: Tuple[str, ...] +BADDY: Tuple[str, ...] +CHASE: Tuple[str, ...] +BA_DING: Tuple[str, ...] +WAWAWAWAA: Tuple[str, ...] +JUMP_UP: Tuple[str, ...] +JUMP_DOWN: Tuple[str, ...] +POWER_UP: Tuple[str, ...] +POWER_DOWN: Tuple[str, ...] + +def set_tempo(ticks: int = ..., bpm: int = ...) -> None: + """ + Sets the approximate tempo for playback. + + A number of ticks (expressed as an integer) constitute a beat. + Each beat is to be played at a certain frequency per minute + (expressed as the more familiar BPM - beats per minute - + also as an integer). + + Suggested default values allow the following useful behaviour: + + music.set_tempo() - reset the tempo to default of ticks = 4, bpm = 120 + music.set_tempo(ticks=8) - change the “definition” of a beat + music.set_tempo(bpm=180) - just change the tempo + + To work out the length of a tick in milliseconds is very simple arithmetic: + 60000/bpm/ticks_per_beat . For the default values that’s + 60000/120/4 = 125 milliseconds or 1 beat = 500 milliseconds. + """ + ... + +def get_tempo(self) -> Tuple[int, int]: + """ + Gets the current tempo as a tuple of integers: (ticks, bpm). + """ + ... + +def play( + music: Union[str, List[str], Tuple[str, ...]], + pin: MicroBitDigitalPin = ..., + wait: bool = True, + loop: bool = False, +) -> None: + """Plays ``music`` containing the musical DSL defined above. + + If ``music`` is a string it is expected to be a single note such as, + ``'c1:4'``. + + If ``music`` is specified as a list of notes (as defined in the section on + the musical DSL, above) then they are played one after the other to perform + a melody. + + In both cases, the ``duration`` and ``octave`` values are reset to + their defaults before the music (whatever it may be) is played. + + An optional argument to specify the output pin can be used to override the + default of ``microbit.pin0``. If we do not want any sound to play we can + use ``pin=None``. + + If ``wait`` is set to ``True``, this function is blocking. + + If ``loop`` is set to ``True``, the tune repeats until ``stop`` is called + (see below) or the blocking call is interrupted. + """ + ... + +def pitch( + frequency: int, duration=..., pin: MicroBitDigitalPin = ..., wait: bool = ... +) -> None: + """Plays a pitch at the integer frequency given for the specified number of + milliseconds. For example, if the frequency is set to 440 and the length to + 1000 then we hear a standard concert A for one second. + + Note that you can only play one pitch on one pin at any one time. + + An optional argument to specify the output pin can be used to override the + default of ``microbit.pin0``. If we do not want any sound to play out of + the pins we can use ``pin=None``. + + If ``wait`` is set to ``True``, this function is blocking. + + If ``duration`` is negative the pitch is played continuously until either + the blocking call is interrupted or, in the case of a background call, a + new frequency is set or ``stop`` is called (see below). + """ + ... + +def stop(pin: MicroBitDigitalPin = pin0) -> None: + """Stops all music playback on the built-in speaker and any pin outputting + sound. An optional argument can be provided to specify a pin, eg. + ``music.stop(pin1)``. + """ + +def reset() -> None: + """Resets the state of the following attributes in the following way: + + * ``ticks = 4`` + * ``bpm = 120`` + * ``duration = 4`` + * ``octave = 4`` + """ + ... diff --git a/typeshed/stdlib/neopixel.pyi b/typeshed/stdlib/neopixel.pyi new file mode 100644 index 0000000..26c2bc1 --- /dev/null +++ b/typeshed/stdlib/neopixel.pyi @@ -0,0 +1,80 @@ +""" +The ``neopixel`` module lets you use NeoPixel (WS2812) individually addressable +RGB and RGBW **V2** LED strips with the micro:bit. Note to use the ``neopixel`` module, you +need to import it separately with:: + + import neopixel + +.. note:: + + From our tests, the Microbit NeoPixel module can drive up to around 256 + NeoPixels. Anything above that and you may experience weird bugs and + issues. The micro:bit can only supply 90mA **V1** or 190mA **V2** to + external devices,larger numbers of NeoPixels require an external power + supply with common ground. + + NeoPixels are designed to work at 5V, but luckily they still function using + the 3V supply of the BBC micro:bit. Please note that the micro:bit edge + connector should not be connected to anything supplying 5V. + +NeoPixels are fun strips of multi-coloured programmable LEDs. This module +contains everything to plug them into a micro:bit and create funky displays, +art and games. + +To connect a strip of neopixels you'll need to attach the micro:bit as shown +below (assuming you want to drive the pixels from pin 0 - you can connect +neopixels to pins 1 and 2 too). The label on the crocodile clip tells you where +to attach the other end on the neopixel strip. The VDD pin may be labelled +as something else on some variants of neopixels - for example "V+". In some +cases it may be called "+5V" and it is only safe to use this if you have no +other 5V devices connected. + +.. warning:: + + Do not use the 3v connector on the micro:bit to power any more than 8 + Neopixels at a time. + + If you wish to use more than 8 Neopixels, you must use a separate 3v-5v + power supply for the Neopixel power pin. +""" +from .microbit import MicroBitDigitalPin +from typing import Tuple + +class NeoPixel: + def __init__(self, pin: MicroBitDigitalPin, n: int, bpp: int = ...) -> None: + """ + Initialise a new strip of ``n`` number of neopixel LEDs controlled via pin + ``pin``. The **V2** micro:bit can also support RGBW neopixels, so a third + argument can be passed to ``NeoPixel`` to indicate the number of bytes per + pixel (bpp). For RGBW, this is is ``4`` rather than the default of ``3`` for + RGB and GRB. + """ + ... + def clear(self) -> None: + """ + Clear all the pixels. + """ + ... + def show(self) -> None: + """ + Show the pixels. Must be called for any updates to become visible. + """ + ... + def write(self) -> None: + """ + **V2** Show the pixels. Must be called for any updates to become visible. + + Equivalent to ``show``. + """ + ... + def fill(self, colour: Tuple[int, ...]) -> None: + """ + **V2** Colour all pixels a given RGB/RGBW value. The `colour` argument + should be a tuple of the same length as the mumber of bytes per pixel + (bpp). For example ``fill((0,0,255))``. Use in conjunction with + ``show()`` to update the Neopixels. + """ + ... + def __setitem__(self, key: int, value: Tuple[int, ...]) -> None: ... + def __getitem__(self, key: int) -> Tuple[int, ...]: ... + def __len__(self) -> int: ... diff --git a/typeshed/stdlib/os.pyi b/typeshed/stdlib/os.pyi new file mode 100644 index 0000000..c3df8b0 --- /dev/null +++ b/typeshed/stdlib/os.pyi @@ -0,0 +1 @@ +from uos import * diff --git a/typeshed/stdlib/radio.pyi b/typeshed/stdlib/radio.pyi new file mode 100644 index 0000000..630d54c --- /dev/null +++ b/typeshed/stdlib/radio.pyi @@ -0,0 +1,159 @@ +"""The ``radio`` module allows devices to work together via simple wireless +networks. + +The radio module is conceptually very simple: + +* Broadcast messages are of a certain configurable length (up to 251 bytes). +* Messages received are read from a queue of configurable size (the larger the queue the more RAM is used). If the queue is full, new messages are ignored. Reading a message removes it from the queue. +* Messages are broadcast and received on a preselected channel (numbered 0-83). +* Broadcasts are at a certain level of power - more power means more range. +* Messages are filtered by address (like a house number) and group (like a named recipient at the specified address). +* The rate of throughput can be one of three pre-determined settings. +* Send and receive bytes to work with arbitrary data. +* Use `receive_full` to obtain full details about an incoming message: the data, receiving signal strength, and a microsecond timestamp when the message arrived. +* As a convenience for children, it's easy to send and receive messages as strings. +* The default configuration is both sensible and compatible with other platforms that target the BBC micro:bit. + +To access this module you need to:: + + import radio +""" + +from typing import Optional, Tuple + +RATE_250KBIT: int +"""Constant used to indicate a throughput of 256 Kbit a second. Not available on **V2**.""" + +RATE_1MBIT: int +"""Constant used to indicate a throughput of 1 MBit a second.""" + +RATE_2MBIT: int +"""Constant used to indicate a throughput of 2 MBit a second.""" + +def on() -> None: + """Turns the radio on. This needs to be explicitly called since the radio + draws power and takes up memory that you may otherwise need. + """ + ... + +def off() -> None: + """Turns off the radio, thus saving power and memory.""" + ... + +def config( + length: int = 32, + queue: int = 3, + channel: int = 7, + power: int = 6, + address: int = 0x75626974, + group: int = 0, + data_rate: int = RATE_1MBIT, +) -> None: + """Configures various keyword based settings relating to the radio. The + available settings and their sensible default values are listed below. + + The ``length`` (default=32) defines the maximum length, in bytes, of a + message sent via the radio. It can be up to 251 bytes long (254 - 3 bytes + for S0, LENGTH and S1 preamble). + + The ``queue`` (default=3) specifies the number of messages that can be + stored on the incoming message queue. If there are no spaces left on the + queue for incoming messages, then the incoming message is dropped. + + The ``channel`` (default=7) can be an integer value from 0 to 83 + (inclusive) that defines an arbitrary "channel" to which the radio is + tuned. Messages will be sent via this channel and only messages received + via this channel will be put onto the incoming message queue. Each step is + 1MHz wide, based at 2400MHz. + + The ``power`` (default=6) is an integer value from 0 to 7 (inclusive) to + indicate the strength of signal used when broadcasting a message. The + higher the value the stronger the signal, but the more power is consumed + by the device. The numbering translates to positions in the following list + of dBm (decibel milliwatt) values: -30, -20, -16, -12, -8, -4, 0, 4. + + The ``address`` (default=0x75626974) is an arbitrary name, expressed as a + 32-bit address, that's used to filter incoming packets at the hardware + level, keeping only those that match the address you set. The default used + by other micro:bit related platforms is the default setting used here. + + The ``group`` (default=0) is an 8-bit value (0-255) used with the + ``address`` when filtering messages. Conceptually, "address" is like a + house/office address and "group" is like the person at that address to + which you want to send your message. + + The ``data_rate`` (default=radio.RATE_1MBIT) indicates the speed at which + data throughput takes place. Can be one of the following contants defined + in the ``radio`` module : ``RATE_250KBIT``, ``RATE_1MBIT`` or + ``RATE_2MBIT``. + + If ``config`` is not called then the defaults described above are assumed. + """ + ... + +def reset() -> None: + """Reset the settings to their default values (as listed in the documentation + for the ``config`` function above). + """ + ... + +def send_bytes(message: bytes) -> None: + """Sends a message containing bytes.""" + ... + +def receive_bytes() -> Optional[bytes]: + """Receive the next incoming message on the message queue. Returns ``None`` if + there are no pending messages. Messages are returned as bytes. + """ + ... + +def receive_bytes_into(buffer: bytearray) -> Optional[int]: + """Receive the next incoming message on the message queue. Copies the message + into ``buffer``, trimming the end of the message if necessary. + Returns ``None`` if there are no pending messages, otherwise it returns the length + of the message (which might be more than the length of the buffer). + """ + ... + +def send(message: str) -> None: + """Sends a message string. This is the equivalent of + ``send_bytes(bytes(message, 'utf8'))`` but with ``b'\x01\x00\x01'`` + prepended to the front (to make it compatible with other platforms that + target the micro:bit). + """ + ... + +def receive() -> Optional[str]: + """Works in exactly the same way as ``receive_bytes`` but returns + whatever was sent. + + Currently, it's equivalent to ``str(receive_bytes(), 'utf8')`` but with a + check that the the first three bytes are ``b'\x01\x00\x01'`` (to make it + compatible with other platforms that may target the micro:bit). It strips + the prepended bytes before converting to a string. + + A ``ValueError`` exception is raised if conversion to string fails. + """ + ... + +def receive_full() -> Tuple[bytes, int, int]: + """Returns a tuple containing three values representing the next incoming + message on the message queue. If there are no pending messages then + ``None`` is returned. + + The three values in the tuple represent: + + * the next incoming message on the message queue as bytes. + * the RSSI (signal strength): a value between 0 (strongest) and -255 (weakest) as measured in dBm. + * a microsecond timestamp: the value returned by ``time.ticks_us()`` when the message was received. + + For example:: + + details = radio.receive_full() + if details: + msg, rssi, timestamp = details + + This function is useful for providing information needed for triangulation + and/or triliteration with other micro:bit devices. + """ + ... diff --git a/typeshed/stdlib/random.pyi b/typeshed/stdlib/random.pyi new file mode 100644 index 0000000..667e5ae --- /dev/null +++ b/typeshed/stdlib/random.pyi @@ -0,0 +1 @@ +from urandom import * diff --git a/typeshed/stdlib/speech.pyi b/typeshed/stdlib/speech.pyi new file mode 100644 index 0000000..a8820db --- /dev/null +++ b/typeshed/stdlib/speech.pyi @@ -0,0 +1,87 @@ +"""This module makes the micro:bit talk, sing and make other speech like sounds. +By default sound output will be via the edge connector on pin 0 and the +:doc:`built-in speaker ` **V2**. You can connect wired headphones or +a speaker to pin 0 and GND on the edge connector to hear the sound: + +.. note:: + + This work is based upon the amazing reverse engineering efforts of + Sebastian Macke based upon an old text-to-speech (TTS) program called SAM + (Software Automated Mouth) originally released in 1982 for the + Commodore 64. The result is a small C library that we have adopted and + adapted for the micro:bit. You can find out more from + `his homepage `_. Much of + the information in this document was gleaned from the original user's + manual which can be found + `here `_. + +The speech synthesiser can produce around 2.5 seconds worth of sound from up to +255 characters of textual input. + +To access this module you need to:: + + import speech +""" + +from .microbit import MicroBitDigitalPin, pin0 + +def translate(words: str) -> str: + """Given English words in the string ``words``, return a string containing + a best guess at the appropriate phonemes to pronounce. The output is + generated from this + `text to phoneme translation table `_. + + This function should be used to generate a first approximation of phonemes + that can be further hand-edited to improve accuracy, inflection and + emphasis. + """ + ... + +def pronounce( + phonemes: str, + pitch: int = 64, + speed: int = 72, + mouth: int = 128, + throat: int = 128, + pin: MicroBitDigitalPin = pin0, +) -> None: + """Pronounce the phonemes in the string ``phonemes``. See below for details of + how to use phonemes to finely control the output of the speech synthesiser. + Override the optional pitch, speed, mouth and throat settings to change the + timbre (quality) of the voice. + + For micro:bit **V2** an optional argument to specify the output pin can be + used to override the default of ``pin0``. If we do not want any sound to + play out of the pins can use ``pin=None``. + """ + ... + +def say( + words: str, + pitch: int = 64, + speed: int = 72, + mouth: int = 128, + throat: int = 128, + pin: MicroBitDigitalPin = pin0, +) -> None: + """Say the English words in the string ``words``. The result is semi-accurate + for English. Override the optional pitch, speed, mouth and throat + settings to change the timbre (quality) of the voice. This is a short-hand + equivalent of: ``speech.pronounce(speech.translate(words))`` + """ + ... + +def sing( + phonemes: str, + pitch: int = 64, + speed: int = 72, + mouth: int = 128, + throat: int = 128, + pin: MicroBitDigitalPin = pin0, +) -> None: + """Sing the phonemes contained in the string ``phonemes``. Changing the pitch + and duration of the note is described below. Override the optional pitch, + speed, mouth and throat settings to change the timbre (quality) of the + voice. + """ + ... diff --git a/typeshed/stdlib/struct.pyi b/typeshed/stdlib/struct.pyi new file mode 100644 index 0000000..677ad73 --- /dev/null +++ b/typeshed/stdlib/struct.pyi @@ -0,0 +1 @@ +from ustruct import * diff --git a/typeshed/stdlib/sys.pyi b/typeshed/stdlib/sys.pyi new file mode 100644 index 0000000..f163572 --- /dev/null +++ b/typeshed/stdlib/sys.pyi @@ -0,0 +1 @@ +from usys import * diff --git a/typeshed/stdlib/this.pyi b/typeshed/stdlib/this.pyi new file mode 100644 index 0000000..faf492b --- /dev/null +++ b/typeshed/stdlib/this.pyi @@ -0,0 +1 @@ +def authors() -> str: ... diff --git a/typeshed/stdlib/time.pyi b/typeshed/stdlib/time.pyi new file mode 100644 index 0000000..bc54271 --- /dev/null +++ b/typeshed/stdlib/time.pyi @@ -0,0 +1 @@ +from utime import * diff --git a/typeshed/stdlib/typing.pyi b/typeshed/stdlib/typing.pyi new file mode 100644 index 0000000..a494557 --- /dev/null +++ b/typeshed/stdlib/typing.pyi @@ -0,0 +1,716 @@ +import collections # Needed by aliases like DefaultDict, see mypy issue 2986 +import sys +from abc import ABCMeta, abstractmethod +from types import BuiltinFunctionType, CodeType, FrameType, FunctionType, MethodType, ModuleType, TracebackType +from typing_extensions import Literal as _Literal + +if sys.version_info >= (3, 7): + from types import MethodDescriptorType, MethodWrapperType, WrapperDescriptorType + +if sys.version_info >= (3, 9): + from types import GenericAlias + +# Definitions of special type checking related constructs. Their definitions +# are not used, so their value does not matter. + +Any = object() + +class TypeVar: + __name__: str + __bound__: Optional[Type[Any]] + __constraints__: Tuple[Type[Any], ...] + __covariant__: bool + __contravariant__: bool + def __init__( + self, + name: str, + *constraints: Type[Any], + bound: Union[None, Type[Any], str] = ..., + covariant: bool = ..., + contravariant: bool = ..., + ) -> None: ... + +_promote = object() + +class _SpecialForm: + def __getitem__(self, typeargs: Any) -> object: ... + +_F = TypeVar("_F", bound=Callable[..., Any]) + +def overload(func: _F) -> _F: ... + +Union: _SpecialForm = ... +Optional: _SpecialForm = ... +Tuple: _SpecialForm = ... +Generic: _SpecialForm = ... +# Protocol is only present in 3.8 and later, but mypy needs it unconditionally +Protocol: _SpecialForm = ... +Callable: _SpecialForm = ... +Type: _SpecialForm = ... +ClassVar: _SpecialForm = ... +if sys.version_info >= (3, 8): + Final: _SpecialForm = ... + def final(f: _F) -> _F: ... + Literal: _SpecialForm = ... + # TypedDict is a (non-subscriptable) special form. + TypedDict: object + +if sys.version_info < (3, 7): + class GenericMeta(type): ... + +if sys.version_info >= (3, 10): + class ParamSpecArgs: + __origin__: ParamSpec + def __init__(self, origin: ParamSpec) -> None: ... + class ParamSpecKwargs: + __origin__: ParamSpec + def __init__(self, origin: ParamSpec) -> None: ... + class ParamSpec: + __name__: str + __bound__: Optional[Type[Any]] + __covariant__: bool + __contravariant__: bool + def __init__( + self, name: str, *, bound: Union[None, Type[Any], str] = ..., contravariant: bool = ..., covariant: bool = ... + ) -> None: ... + @property + def args(self) -> ParamSpecArgs: ... + @property + def kwargs(self) -> ParamSpecKwargs: ... + Concatenate: _SpecialForm = ... + TypeAlias: _SpecialForm = ... + TypeGuard: _SpecialForm = ... + +# Return type that indicates a function does not return. +# This type is equivalent to the None type, but the no-op Union is necessary to +# distinguish the None type from the None value. +NoReturn = Union[None] + +# These type variables are used by the container types. +_T = TypeVar("_T") +_S = TypeVar("_S") +_KT = TypeVar("_KT") # Key type. +_VT = TypeVar("_VT") # Value type. +_T_co = TypeVar("_T_co", covariant=True) # Any type covariant containers. +_V_co = TypeVar("_V_co", covariant=True) # Any type covariant containers. +_KT_co = TypeVar("_KT_co", covariant=True) # Key type covariant containers. +_VT_co = TypeVar("_VT_co", covariant=True) # Value type covariant containers. +_T_contra = TypeVar("_T_contra", contravariant=True) # Ditto contravariant. +_TC = TypeVar("_TC", bound=Type[object]) + +def no_type_check(arg: _F) -> _F: ... +def no_type_check_decorator(decorator: _F) -> _F: ... + +# Type aliases and type constructors + +class _Alias: + # Class for defining generic aliases for library types. + def __getitem__(self, typeargs: Any) -> Any: ... + +List = _Alias() +Dict = _Alias() +DefaultDict = _Alias() +Set = _Alias() +FrozenSet = _Alias() +Counter = _Alias() +Deque = _Alias() +ChainMap = _Alias() + +if sys.version_info >= (3, 7): + OrderedDict = _Alias() + +if sys.version_info >= (3, 9): + Annotated: _SpecialForm = ... + +# Predefined type variables. +AnyStr = TypeVar("AnyStr", str, bytes) + +# Abstract base classes. + +def runtime_checkable(cls: _TC) -> _TC: ... +@runtime_checkable +class SupportsInt(Protocol, metaclass=ABCMeta): + @abstractmethod + def __int__(self) -> int: ... + +@runtime_checkable +class SupportsFloat(Protocol, metaclass=ABCMeta): + @abstractmethod + def __float__(self) -> float: ... + +@runtime_checkable +class SupportsComplex(Protocol, metaclass=ABCMeta): + @abstractmethod + def __complex__(self) -> complex: ... + +@runtime_checkable +class SupportsBytes(Protocol, metaclass=ABCMeta): + @abstractmethod + def __bytes__(self) -> bytes: ... + +if sys.version_info >= (3, 8): + @runtime_checkable + class SupportsIndex(Protocol, metaclass=ABCMeta): + @abstractmethod + def __index__(self) -> int: ... + +@runtime_checkable +class SupportsAbs(Protocol[_T_co]): + @abstractmethod + def __abs__(self) -> _T_co: ... + +@runtime_checkable +class SupportsRound(Protocol[_T_co]): + @overload + @abstractmethod + def __round__(self) -> int: ... + @overload + @abstractmethod + def __round__(self, ndigits: int) -> _T_co: ... + +@runtime_checkable +class Sized(Protocol, metaclass=ABCMeta): + @abstractmethod + def __len__(self) -> int: ... + +@runtime_checkable +class Hashable(Protocol, metaclass=ABCMeta): + # TODO: This is special, in that a subclass of a hashable class may not be hashable + # (for example, list vs. object). It's not obvious how to represent this. This class + # is currently mostly useless for static checking. + @abstractmethod + def __hash__(self) -> int: ... + +@runtime_checkable +class Iterable(Protocol[_T_co]): + @abstractmethod + def __iter__(self) -> Iterator[_T_co]: ... + +@runtime_checkable +class Iterator(Iterable[_T_co], Protocol[_T_co]): + @abstractmethod + def __next__(self) -> _T_co: ... + def __iter__(self) -> Iterator[_T_co]: ... + +@runtime_checkable +class Reversible(Iterable[_T_co], Protocol[_T_co]): + @abstractmethod + def __reversed__(self) -> Iterator[_T_co]: ... + +class Generator(Iterator[_T_co], Generic[_T_co, _T_contra, _V_co]): + def __next__(self) -> _T_co: ... + @abstractmethod + def send(self, __value: _T_contra) -> _T_co: ... + @overload + @abstractmethod + def throw( + self, __typ: Type[BaseException], __val: Union[BaseException, object] = ..., __tb: Optional[TracebackType] = ... + ) -> _T_co: ... + @overload + @abstractmethod + def throw(self, __typ: BaseException, __val: None = ..., __tb: Optional[TracebackType] = ...) -> _T_co: ... + def close(self) -> None: ... + def __iter__(self) -> Generator[_T_co, _T_contra, _V_co]: ... + @property + def gi_code(self) -> CodeType: ... + @property + def gi_frame(self) -> FrameType: ... + @property + def gi_running(self) -> bool: ... + @property + def gi_yieldfrom(self) -> Optional[Generator[Any, Any, Any]]: ... + +@runtime_checkable +class Awaitable(Protocol[_T_co]): + @abstractmethod + def __await__(self) -> Generator[Any, None, _T_co]: ... + +class Coroutine(Awaitable[_V_co], Generic[_T_co, _T_contra, _V_co]): + __name__: str + __qualname__: str + @property + def cr_await(self) -> Optional[Any]: ... + @property + def cr_code(self) -> CodeType: ... + @property + def cr_frame(self) -> FrameType: ... + @property + def cr_running(self) -> bool: ... + @abstractmethod + def send(self, __value: _T_contra) -> _T_co: ... + @overload + @abstractmethod + def throw( + self, __typ: Type[BaseException], __val: Union[BaseException, object] = ..., __tb: Optional[TracebackType] = ... + ) -> _T_co: ... + @overload + @abstractmethod + def throw(self, __typ: BaseException, __val: None = ..., __tb: Optional[TracebackType] = ...) -> _T_co: ... + @abstractmethod + def close(self) -> None: ... + +# NOTE: This type does not exist in typing.py or PEP 484. +# The parameters correspond to Generator, but the 4th is the original type. +class AwaitableGenerator( + Awaitable[_V_co], Generator[_T_co, _T_contra, _V_co], Generic[_T_co, _T_contra, _V_co, _S], metaclass=ABCMeta +): ... + +@runtime_checkable +class AsyncIterable(Protocol[_T_co]): + @abstractmethod + def __aiter__(self) -> AsyncIterator[_T_co]: ... + +@runtime_checkable +class AsyncIterator(AsyncIterable[_T_co], Protocol[_T_co]): + @abstractmethod + def __anext__(self) -> Awaitable[_T_co]: ... + def __aiter__(self) -> AsyncIterator[_T_co]: ... + +class AsyncGenerator(AsyncIterator[_T_co], Generic[_T_co, _T_contra]): + @abstractmethod + def __anext__(self) -> Awaitable[_T_co]: ... + @abstractmethod + def asend(self, __value: _T_contra) -> Awaitable[_T_co]: ... + @overload + @abstractmethod + def athrow( + self, __typ: Type[BaseException], __val: Union[BaseException, object] = ..., __tb: Optional[TracebackType] = ... + ) -> Awaitable[_T_co]: ... + @overload + @abstractmethod + def athrow(self, __typ: BaseException, __val: None = ..., __tb: Optional[TracebackType] = ...) -> Awaitable[_T_co]: ... + @abstractmethod + def aclose(self) -> Awaitable[None]: ... + @abstractmethod + def __aiter__(self) -> AsyncGenerator[_T_co, _T_contra]: ... + @property + def ag_await(self) -> Any: ... + @property + def ag_code(self) -> CodeType: ... + @property + def ag_frame(self) -> FrameType: ... + @property + def ag_running(self) -> bool: ... + +@runtime_checkable +class Container(Protocol[_T_co]): + @abstractmethod + def __contains__(self, __x: object) -> bool: ... + +@runtime_checkable +class Collection(Iterable[_T_co], Container[_T_co], Protocol[_T_co]): + # Implement Sized (but don't have it as a base class). + @abstractmethod + def __len__(self) -> int: ... + +_Collection = Collection[_T_co] + +class Sequence(_Collection[_T_co], Reversible[_T_co], Generic[_T_co]): + @overload + @abstractmethod + def __getitem__(self, i: int) -> _T_co: ... + @overload + @abstractmethod + def __getitem__(self, s: slice) -> Sequence[_T_co]: ... + # Mixin methods + def index(self, value: Any, start: int = ..., stop: int = ...) -> int: ... + def count(self, value: Any) -> int: ... + def __contains__(self, x: object) -> bool: ... + def __iter__(self) -> Iterator[_T_co]: ... + def __reversed__(self) -> Iterator[_T_co]: ... + +class MutableSequence(Sequence[_T], Generic[_T]): + @abstractmethod + def insert(self, index: int, value: _T) -> None: ... + @overload + @abstractmethod + def __getitem__(self, i: int) -> _T: ... + @overload + @abstractmethod + def __getitem__(self, s: slice) -> MutableSequence[_T]: ... + @overload + @abstractmethod + def __setitem__(self, i: int, o: _T) -> None: ... + @overload + @abstractmethod + def __setitem__(self, s: slice, o: Iterable[_T]) -> None: ... + @overload + @abstractmethod + def __delitem__(self, i: int) -> None: ... + @overload + @abstractmethod + def __delitem__(self, i: slice) -> None: ... + # Mixin methods + def append(self, value: _T) -> None: ... + def clear(self) -> None: ... + def extend(self, values: Iterable[_T]) -> None: ... + def reverse(self) -> None: ... + def pop(self, index: int = ...) -> _T: ... + def remove(self, value: _T) -> None: ... + def __iadd__(self, x: Iterable[_T]) -> MutableSequence[_T]: ... + +class AbstractSet(_Collection[_T_co], Generic[_T_co]): + @abstractmethod + def __contains__(self, x: object) -> bool: ... + # Mixin methods + def __le__(self, s: AbstractSet[Any]) -> bool: ... + def __lt__(self, s: AbstractSet[Any]) -> bool: ... + def __gt__(self, s: AbstractSet[Any]) -> bool: ... + def __ge__(self, s: AbstractSet[Any]) -> bool: ... + def __and__(self, s: AbstractSet[Any]) -> AbstractSet[_T_co]: ... + def __or__(self, s: AbstractSet[_T]) -> AbstractSet[Union[_T_co, _T]]: ... + def __sub__(self, s: AbstractSet[Any]) -> AbstractSet[_T_co]: ... + def __xor__(self, s: AbstractSet[_T]) -> AbstractSet[Union[_T_co, _T]]: ... + def isdisjoint(self, other: Iterable[Any]) -> bool: ... + +class MutableSet(AbstractSet[_T], Generic[_T]): + @abstractmethod + def add(self, value: _T) -> None: ... + @abstractmethod + def discard(self, value: _T) -> None: ... + # Mixin methods + def clear(self) -> None: ... + def pop(self) -> _T: ... + def remove(self, value: _T) -> None: ... + def __ior__(self, s: AbstractSet[_S]) -> MutableSet[Union[_T, _S]]: ... + def __iand__(self, s: AbstractSet[Any]) -> MutableSet[_T]: ... + def __ixor__(self, s: AbstractSet[_S]) -> MutableSet[Union[_T, _S]]: ... + def __isub__(self, s: AbstractSet[Any]) -> MutableSet[_T]: ... + +class MappingView(Sized): + def __init__(self, mapping: Mapping[Any, Any]) -> None: ... # undocumented + def __len__(self) -> int: ... + +class ItemsView(MappingView, AbstractSet[Tuple[_KT_co, _VT_co]], Generic[_KT_co, _VT_co]): + def __init__(self, mapping: Mapping[_KT_co, _VT_co]) -> None: ... # undocumented + def __and__(self, o: Iterable[Any]) -> Set[Tuple[_KT_co, _VT_co]]: ... + def __rand__(self, o: Iterable[_T]) -> Set[_T]: ... + def __contains__(self, o: object) -> bool: ... + def __iter__(self) -> Iterator[Tuple[_KT_co, _VT_co]]: ... + if sys.version_info >= (3, 8): + def __reversed__(self) -> Iterator[Tuple[_KT_co, _VT_co]]: ... + def __or__(self, o: Iterable[_T]) -> Set[Union[Tuple[_KT_co, _VT_co], _T]]: ... + def __ror__(self, o: Iterable[_T]) -> Set[Union[Tuple[_KT_co, _VT_co], _T]]: ... + def __sub__(self, o: Iterable[Any]) -> Set[Tuple[_KT_co, _VT_co]]: ... + def __rsub__(self, o: Iterable[_T]) -> Set[_T]: ... + def __xor__(self, o: Iterable[_T]) -> Set[Union[Tuple[_KT_co, _VT_co], _T]]: ... + def __rxor__(self, o: Iterable[_T]) -> Set[Union[Tuple[_KT_co, _VT_co], _T]]: ... + +class KeysView(MappingView, AbstractSet[_KT_co], Generic[_KT_co]): + def __init__(self, mapping: Mapping[_KT_co, Any]) -> None: ... # undocumented + def __and__(self, o: Iterable[Any]) -> Set[_KT_co]: ... + def __rand__(self, o: Iterable[_T]) -> Set[_T]: ... + def __contains__(self, o: object) -> bool: ... + def __iter__(self) -> Iterator[_KT_co]: ... + if sys.version_info >= (3, 8): + def __reversed__(self) -> Iterator[_KT_co]: ... + def __or__(self, o: Iterable[_T]) -> Set[Union[_KT_co, _T]]: ... + def __ror__(self, o: Iterable[_T]) -> Set[Union[_KT_co, _T]]: ... + def __sub__(self, o: Iterable[Any]) -> Set[_KT_co]: ... + def __rsub__(self, o: Iterable[_T]) -> Set[_T]: ... + def __xor__(self, o: Iterable[_T]) -> Set[Union[_KT_co, _T]]: ... + def __rxor__(self, o: Iterable[_T]) -> Set[Union[_KT_co, _T]]: ... + +class ValuesView(MappingView, Iterable[_VT_co], Generic[_VT_co]): + def __init__(self, mapping: Mapping[Any, _VT_co]) -> None: ... # undocumented + def __contains__(self, o: object) -> bool: ... + def __iter__(self) -> Iterator[_VT_co]: ... + if sys.version_info >= (3, 8): + def __reversed__(self) -> Iterator[_VT_co]: ... + +@runtime_checkable +class ContextManager(Protocol[_T_co]): + def __enter__(self) -> _T_co: ... + def __exit__( + self, + __exc_type: Optional[Type[BaseException]], + __exc_value: Optional[BaseException], + __traceback: Optional[TracebackType], + ) -> Optional[bool]: ... + +@runtime_checkable +class AsyncContextManager(Protocol[_T_co]): + def __aenter__(self) -> Awaitable[_T_co]: ... + def __aexit__( + self, exc_type: Optional[Type[BaseException]], exc_value: Optional[BaseException], traceback: Optional[TracebackType] + ) -> Awaitable[Optional[bool]]: ... + +class Mapping(_Collection[_KT], Generic[_KT, _VT_co]): + # TODO: We wish the key type could also be covariant, but that doesn't work, + # see discussion in https: //github.com/python/typing/pull/273. + @abstractmethod + def __getitem__(self, k: _KT) -> _VT_co: ... + # Mixin methods + @overload + def get(self, key: _KT) -> Optional[_VT_co]: ... + @overload + def get(self, key: _KT, default: Union[_VT_co, _T]) -> Union[_VT_co, _T]: ... + def items(self) -> AbstractSet[Tuple[_KT, _VT_co]]: ... + def keys(self) -> AbstractSet[_KT]: ... + def values(self) -> ValuesView[_VT_co]: ... + def __contains__(self, o: object) -> bool: ... + +class MutableMapping(Mapping[_KT, _VT], Generic[_KT, _VT]): + @abstractmethod + def __setitem__(self, k: _KT, v: _VT) -> None: ... + @abstractmethod + def __delitem__(self, v: _KT) -> None: ... + def clear(self) -> None: ... + @overload + def pop(self, key: _KT) -> _VT: ... + @overload + def pop(self, key: _KT, default: Union[_VT, _T] = ...) -> Union[_VT, _T]: ... + def popitem(self) -> Tuple[_KT, _VT]: ... + def setdefault(self, key: _KT, default: _VT = ...) -> _VT: ... + # 'update' used to take a Union, but using overloading is better. + # The second overloaded type here is a bit too general, because + # Mapping[Tuple[_KT, _VT], W] is a subclass of Iterable[Tuple[_KT, _VT]], + # but will always have the behavior of the first overloaded type + # at runtime, leading to keys of a mix of types _KT and Tuple[_KT, _VT]. + # We don't currently have any way of forcing all Mappings to use + # the first overload, but by using overloading rather than a Union, + # mypy will commit to using the first overload when the argument is + # known to be a Mapping with unknown type parameters, which is closer + # to the behavior we want. See mypy issue #1430. + @overload + def update(self, __m: Mapping[_KT, _VT], **kwargs: _VT) -> None: ... + @overload + def update(self, __m: Iterable[Tuple[_KT, _VT]], **kwargs: _VT) -> None: ... + @overload + def update(self, **kwargs: _VT) -> None: ... + +Text = str + +TYPE_CHECKING = True + +class IO(Iterator[AnyStr], Generic[AnyStr]): + # TODO use abstract properties + @property + def mode(self) -> str: ... + @property + def name(self) -> str: ... + @abstractmethod + def close(self) -> None: ... + @property + def closed(self) -> bool: ... + @abstractmethod + def fileno(self) -> int: ... + @abstractmethod + def flush(self) -> None: ... + @abstractmethod + def isatty(self) -> bool: ... + @abstractmethod + def read(self, n: int = ...) -> AnyStr: ... + @abstractmethod + def readable(self) -> bool: ... + @abstractmethod + def readline(self, limit: int = ...) -> AnyStr: ... + @abstractmethod + def readlines(self, hint: int = ...) -> list[AnyStr]: ... + @abstractmethod + def seek(self, offset: int, whence: int = ...) -> int: ... + @abstractmethod + def seekable(self) -> bool: ... + @abstractmethod + def tell(self) -> int: ... + @abstractmethod + def truncate(self, size: Optional[int] = ...) -> int: ... + @abstractmethod + def writable(self) -> bool: ... + @abstractmethod + def write(self, s: AnyStr) -> int: ... + @abstractmethod + def writelines(self, lines: Iterable[AnyStr]) -> None: ... + @abstractmethod + def __next__(self) -> AnyStr: ... + @abstractmethod + def __iter__(self) -> Iterator[AnyStr]: ... + @abstractmethod + def __enter__(self) -> IO[AnyStr]: ... + @abstractmethod + def __exit__( + self, t: Optional[Type[BaseException]], value: Optional[BaseException], traceback: Optional[TracebackType] + ) -> Optional[bool]: ... + +class BinaryIO(IO[bytes]): + @abstractmethod + def __enter__(self) -> BinaryIO: ... + +class TextIO(IO[str]): + # TODO use abstractproperty + @property + def buffer(self) -> BinaryIO: ... + @property + def encoding(self) -> str: ... + @property + def errors(self) -> Optional[str]: ... + @property + def line_buffering(self) -> int: ... # int on PyPy, bool on CPython + @property + def newlines(self) -> Any: ... # None, str or tuple + @abstractmethod + def __enter__(self) -> TextIO: ... + +class ByteString(Sequence[int], metaclass=ABCMeta): ... + +class Match(Generic[AnyStr]): + pos: int + endpos: int + lastindex: Optional[int] + lastgroup: Optional[AnyStr] + string: AnyStr + + # The regular expression object whose match() or search() method produced + # this match instance. + re: Pattern[AnyStr] + def expand(self, template: AnyStr) -> AnyStr: ... + # group() returns "AnyStr" or "AnyStr | None", depending on the pattern. + @overload + def group(self, __group: _Literal[0] = ...) -> AnyStr: ... + @overload + def group(self, __group: str | int) -> AnyStr | Any: ... + @overload + def group(self, __group1: str | int, __group2: str | int, *groups: str | int) -> Tuple[AnyStr | Any, ...]: ... + # Each item of groups()'s return tuple is either "AnyStr" or + # "AnyStr | None", depending on the pattern. + @overload + def groups(self) -> Tuple[AnyStr | Any, ...]: ... + @overload + def groups(self, default: _T) -> Tuple[AnyStr | _T, ...]: ... + # Each value in groupdict()'s return dict is either "AnyStr" or + # "AnyStr | None", depending on the pattern. + @overload + def groupdict(self) -> dict[str, AnyStr | Any]: ... + @overload + def groupdict(self, default: _T) -> dict[str, AnyStr | _T]: ... + def start(self, __group: Union[int, str] = ...) -> int: ... + def end(self, __group: Union[int, str] = ...) -> int: ... + def span(self, __group: Union[int, str] = ...) -> Tuple[int, int]: ... + @property + def regs(self) -> Tuple[Tuple[int, int], ...]: ... # undocumented + # __getitem__() returns "AnyStr" or "AnyStr | None", depending on the pattern. + @overload + def __getitem__(self, __key: _Literal[0]) -> AnyStr: ... + @overload + def __getitem__(self, __key: int | str) -> AnyStr | Any: ... + if sys.version_info >= (3, 9): + def __class_getitem__(cls, item: Any) -> GenericAlias: ... + +class Pattern(Generic[AnyStr]): + flags: int + groupindex: Mapping[str, int] + groups: int + pattern: AnyStr + def search(self, string: AnyStr, pos: int = ..., endpos: int = ...) -> Optional[Match[AnyStr]]: ... + def match(self, string: AnyStr, pos: int = ..., endpos: int = ...) -> Optional[Match[AnyStr]]: ... + def fullmatch(self, string: AnyStr, pos: int = ..., endpos: int = ...) -> Optional[Match[AnyStr]]: ... + def split(self, string: AnyStr, maxsplit: int = ...) -> list[AnyStr]: ... + def findall(self, string: AnyStr, pos: int = ..., endpos: int = ...) -> list[Any]: ... + def finditer(self, string: AnyStr, pos: int = ..., endpos: int = ...) -> Iterator[Match[AnyStr]]: ... + @overload + def sub(self, repl: AnyStr, string: AnyStr, count: int = ...) -> AnyStr: ... + @overload + def sub(self, repl: Callable[[Match[AnyStr]], AnyStr], string: AnyStr, count: int = ...) -> AnyStr: ... + @overload + def subn(self, repl: AnyStr, string: AnyStr, count: int = ...) -> Tuple[AnyStr, int]: ... + @overload + def subn(self, repl: Callable[[Match[AnyStr]], AnyStr], string: AnyStr, count: int = ...) -> Tuple[AnyStr, int]: ... + if sys.version_info >= (3, 9): + def __class_getitem__(cls, item: Any) -> GenericAlias: ... + +# Functions + +if sys.version_info >= (3, 7): + _get_type_hints_obj_allowed_types = Union[ + object, + Callable[..., Any], + FunctionType, + BuiltinFunctionType, + MethodType, + ModuleType, + WrapperDescriptorType, + MethodWrapperType, + MethodDescriptorType, + ] +else: + _get_type_hints_obj_allowed_types = Union[ + object, Callable[..., Any], FunctionType, BuiltinFunctionType, MethodType, ModuleType, + ] + +if sys.version_info >= (3, 9): + def get_type_hints( + obj: _get_type_hints_obj_allowed_types, + globalns: Optional[Dict[str, Any]] = ..., + localns: Optional[Dict[str, Any]] = ..., + include_extras: bool = ..., + ) -> Dict[str, Any]: ... + +else: + def get_type_hints( + obj: _get_type_hints_obj_allowed_types, globalns: Optional[Dict[str, Any]] = ..., localns: Optional[Dict[str, Any]] = ... + ) -> Dict[str, Any]: ... + +if sys.version_info >= (3, 8): + def get_origin(tp: Any) -> Optional[Any]: ... + def get_args(tp: Any) -> Tuple[Any, ...]: ... + +@overload +def cast(typ: Type[_T], val: Any) -> _T: ... +@overload +def cast(typ: str, val: Any) -> Any: ... +@overload +def cast(typ: object, val: Any) -> Any: ... + +# Type constructors + +# NamedTuple is special-cased in the type checker +class NamedTuple(Tuple[Any, ...]): + _field_types: collections.OrderedDict[str, Type[Any]] + _field_defaults: Dict[str, Any] = ... + _fields: Tuple[str, ...] + _source: str + def __init__(self, typename: str, fields: Iterable[Tuple[str, Any]] = ..., **kwargs: Any) -> None: ... + @classmethod + def _make(cls: Type[_T], iterable: Iterable[Any]) -> _T: ... + if sys.version_info >= (3, 8): + def _asdict(self) -> Dict[str, Any]: ... + else: + def _asdict(self) -> collections.OrderedDict[str, Any]: ... + def _replace(self: _T, **kwargs: Any) -> _T: ... + +# Internal mypy fallback type for all typed dicts (does not exist at runtime) +class _TypedDict(Mapping[str, object], metaclass=ABCMeta): + def copy(self: _T) -> _T: ... + # Using NoReturn so that only calls using mypy plugin hook that specialize the signature + # can go through. + def setdefault(self, k: NoReturn, default: object) -> object: ... + # Mypy plugin hook for 'pop' expects that 'default' has a type variable type. + def pop(self, k: NoReturn, default: _T = ...) -> object: ... # type: ignore + def update(self: _T, __m: _T) -> None: ... + def __delitem__(self, k: NoReturn) -> None: ... + def items(self) -> ItemsView[str, object]: ... + def keys(self) -> KeysView[str]: ... + def values(self) -> ValuesView[object]: ... + def __or__(self: _T, __value: _T) -> _T: ... + def __ior__(self: _T, __value: _T) -> _T: ... + +def NewType(name: str, tp: Type[_T]) -> Type[_T]: ... + +# This itself is only available during type checking +def type_check_only(func_or_cls: _F) -> _F: ... + +if sys.version_info >= (3, 7): + class ForwardRef: + __forward_arg__: str + __forward_code__: CodeType + __forward_evaluated__: bool + __forward_value__: Optional[Any] + __forward_is_argument__: bool + def __init__(self, arg: str, is_argument: bool = ...) -> None: ... + def _evaluate(self, globalns: Optional[Dict[str, Any]], localns: Optional[Dict[str, Any]]) -> Optional[Any]: ... + def __eq__(self, other: Any) -> bool: ... + def __hash__(self) -> int: ... + def __repr__(self) -> str: ... + +if sys.version_info >= (3, 10): + def is_typeddict(tp: Any) -> bool: ... diff --git a/typeshed/stdlib/typing_extensions.pyi b/typeshed/stdlib/typing_extensions.pyi new file mode 100644 index 0000000..b97d0fd --- /dev/null +++ b/typeshed/stdlib/typing_extensions.pyi @@ -0,0 +1,129 @@ +import abc +import sys +from typing import ( + TYPE_CHECKING as TYPE_CHECKING, + Any, + AsyncContextManager as AsyncContextManager, + AsyncGenerator as AsyncGenerator, + AsyncIterable as AsyncIterable, + AsyncIterator as AsyncIterator, + Awaitable as Awaitable, + Callable, + ChainMap as ChainMap, + ClassVar as ClassVar, + ContextManager as ContextManager, + Coroutine as Coroutine, + Counter as Counter, + DefaultDict as DefaultDict, + Deque as Deque, + Dict, + ItemsView, + KeysView, + Mapping, + NewType as NewType, + NoReturn as NoReturn, + Optional, + Text as Text, + Tuple, + Type as Type, + TypeVar, + Union, + ValuesView, + _Alias, + overload as overload, +) + +_T = TypeVar("_T") +_F = TypeVar("_F", bound=Callable[..., Any]) +_TC = TypeVar("_TC", bound=Type[object]) + +class _SpecialForm: + def __getitem__(self, typeargs: Any) -> Any: ... + +def runtime_checkable(cls: _TC) -> _TC: ... + +# This alias for above is kept here for backwards compatibility. +runtime = runtime_checkable +Protocol: _SpecialForm = ... +Final: _SpecialForm = ... + +def final(f: _F) -> _F: ... + +Literal: _SpecialForm = ... + +def IntVar(name: str) -> Any: ... # returns a new TypeVar + +# Internal mypy fallback type for all typed dicts (does not exist at runtime) +class _TypedDict(Mapping[str, object], metaclass=abc.ABCMeta): + def copy(self: _T) -> _T: ... + # Using NoReturn so that only calls using mypy plugin hook that specialize the signature + # can go through. + def setdefault(self, k: NoReturn, default: object) -> object: ... + # Mypy plugin hook for 'pop' expects that 'default' has a type variable type. + def pop(self, k: NoReturn, default: _T = ...) -> object: ... # type: ignore + def update(self: _T, __m: _T) -> None: ... + def items(self) -> ItemsView[str, object]: ... + def keys(self) -> KeysView[str]: ... + def values(self) -> ValuesView[object]: ... + def __delitem__(self, k: NoReturn) -> None: ... + +# TypedDict is a (non-subscriptable) special form. +TypedDict: object = ... + +OrderedDict = _Alias() + +def get_type_hints( + obj: Callable[..., Any], + globalns: Optional[Dict[str, Any]] = ..., + localns: Optional[Dict[str, Any]] = ..., + include_extras: bool = ..., +) -> Dict[str, Any]: ... + +if sys.version_info >= (3, 7): + def get_args(tp: Any) -> Tuple[Any, ...]: ... + def get_origin(tp: Any) -> Optional[Any]: ... + +Annotated: _SpecialForm = ... +_AnnotatedAlias: Any = ... # undocumented + +@runtime_checkable +class SupportsIndex(Protocol, metaclass=abc.ABCMeta): + @abc.abstractmethod + def __index__(self) -> int: ... + +# PEP 612 support for Python < 3.9 +if sys.version_info >= (3, 10): + from typing import Concatenate as Concatenate, ParamSpec as ParamSpec, TypeAlias as TypeAlias, TypeGuard as TypeGuard +else: + class ParamSpecArgs: + __origin__: ParamSpec + def __init__(self, origin: ParamSpec) -> None: ... + class ParamSpecKwargs: + __origin__: ParamSpec + def __init__(self, origin: ParamSpec) -> None: ... + class ParamSpec: + __name__: str + __bound__: Optional[Type[Any]] + __covariant__: bool + __contravariant__: bool + def __init__( + self, name: str, *, bound: Union[None, Type[Any], str] = ..., contravariant: bool = ..., covariant: bool = ... + ) -> None: ... + @property + def args(self) -> ParamSpecArgs: ... + @property + def kwargs(self) -> ParamSpecKwargs: ... + Concatenate: _SpecialForm = ... + TypeAlias: _SpecialForm = ... + TypeGuard: _SpecialForm = ... + +# PEP 646 +Unpack: _SpecialForm = ... + +class TypeVarTuple: + __name__: str + def __init__(self, name: str) -> None: ... + +# PEP 655 +Required: _SpecialForm = ... +NotRequired: _SpecialForm = ... diff --git a/typeshed/stdlib/uarray.pyi b/typeshed/stdlib/uarray.pyi new file mode 100644 index 0000000..1e4e630 --- /dev/null +++ b/typeshed/stdlib/uarray.pyi @@ -0,0 +1,42 @@ +from typing import Generic, Iterable, MutableSequence, TypeVar, Union, overload +from typing_extensions import Literal + +_IntTypeCode = Literal["b", "B", "h", "H", "i", "I", "l", "L", "q", "Q"] +_FloatTypeCode = Literal["f", "d"] +_TypeCode = Union[_IntTypeCode, _FloatTypeCode] + +_T = TypeVar("_T", int, float) + +class array(MutableSequence[_T], Generic[_T]): + @overload + def __init__( + self: array[int], + typecode: _IntTypeCode, + __initializer: Union[bytes, Iterable[_T]] = ..., + ) -> None: ... + @overload + def __init__( + self: array[float], + typecode: _FloatTypeCode, + __initializer: Union[bytes, Iterable[_T]] = ..., + ) -> None: ... + @overload + def __init__( + self, typecode: str, __initializer: Union[bytes, Iterable[_T]] = ... + ) -> None: ... + def append(self, __v: _T) -> None: ... + def decode(self) -> str: ... + def extend(self, __bb: Iterable[_T]) -> None: ... + def __len__(self) -> int: ... + @overload + def __getitem__(self, i: int) -> _T: ... + @overload + def __getitem__(self, s: slice) -> array[_T]: ... + @overload # type: ignore # Overrides MutableSequence + def __setitem__(self, i: int, o: _T) -> None: ... + @overload + def __setitem__(self, s: slice, o: array[_T]) -> None: ... + def __add__(self, x: array[_T]) -> array[_T]: ... + def __iadd__(self, x: array[_T]) -> array[_T]: ... # type: ignore # Overrides MutableSequence + +ArrayType = array diff --git a/typeshed/stdlib/ucollections.pyi b/typeshed/stdlib/ucollections.pyi new file mode 100644 index 0000000..9400561 --- /dev/null +++ b/typeshed/stdlib/ucollections.pyi @@ -0,0 +1 @@ +from collections import * diff --git a/typeshed/stdlib/uerrno.pyi b/typeshed/stdlib/uerrno.pyi new file mode 100644 index 0000000..6ff1c70 --- /dev/null +++ b/typeshed/stdlib/uerrno.pyi @@ -0,0 +1,26 @@ +from typing import Mapping + +errorcode: Mapping[int, str] + +EACCES: int +EADDRINUSE: int +EAGAIN: int +EALREADY: int +EBADF: int +ECONNABORTED: int +ECONNREFUSED: int +ECONNRESET: int +EEXIST: int +EHOSTUNREACH: int +EINPROGRESS: int +EINVAL: int +EIO: int +EISDIR: int +ENOBUFS: int +ENODEV: int +ENOENT: int +ENOMEM: int +ENOTCONN: int +EOPNOTSUPP: int +EPERM: int +ETIMEDOUT: int diff --git a/typeshed/stdlib/uos.pyi b/typeshed/stdlib/uos.pyi new file mode 100644 index 0000000..feab7c8 --- /dev/null +++ b/typeshed/stdlib/uos.pyi @@ -0,0 +1,48 @@ +"""MicroPython contains an ``os`` module based upon the ``os`` module in the +Python standard library. It's used for accessing what would traditionally be +termed as operating system dependent functionality. Since there is no operating +system in MicroPython the module provides functions relating to the management +of the simple on-device persistent file system and information about the +current system. + +To access this module you need to:: + + import os +""" + +from typing import List + +def listdir() -> List[str]: + """Returns a list of the names of all the files contained within the local + persistent on-device file system. + """ + ... + +def remove(filename: str) -> None: + """Removes (deletes) the file named in the argument ``filename``. If the file + does not exist an ``OSError`` exception will occur. + """ + ... + +def size(filename: str) -> int: + """Returns the size, in bytes, of the file named in the argument ``filename``. + If the file does not exist an ``OSError`` exception will occur. + """ + +def uname() -> str: + """Returns information identifying the current operating system. The return + value is an object with five attributes: + + * ``sysname`` - operating system name + * ``nodename`` - name of machine on network (implementation-defined) + * ``release`` - operating system release + * ``version`` - operating system version + * ``machine`` - hardware identifier + + .. note:: + + There is no underlying operating system in MicroPython. As a result the + information returned by the ``uname`` function is mostly useful for + versioning details. + """ + ... diff --git a/typeshed/stdlib/urandom.pyi b/typeshed/stdlib/urandom.pyi new file mode 100644 index 0000000..6307960 --- /dev/null +++ b/typeshed/stdlib/urandom.pyi @@ -0,0 +1,64 @@ +""" +This module is based upon the ``random`` module in the Python standard library. +It contains functions for generating random behaviour. + +To access this module you need to:: + + import random +""" +from typing import TypeVar, Sequence, Union, overload + +def getrandbits(n: int) -> int: + """Returns an integer with ``n`` random bits. + + .. warning:: + + Because the underlying generator function returns at most 30 bits, ``n`` + may only be a value between 1-30 (inclusive).""" + ... + +def seed(n: int) -> None: + """Initialize the random number generator with a known integer ``n``. This + will give you reproducibly deterministic randomness from a given starting + state (``n``). + """ + ... + +def randint(a: int, b: int) -> int: + """Return a random integer ``N`` such that ``a <= N <= b``. Alias for + ``randrange(a, b+1)``. + """ + ... + +@overload +def randrange(stop: int) -> int: + """Return a randomly selected integer between zero and up to (but not + including) ``stop``. + """ + ... + +@overload +def randrange(start: int, stop: Union[int, None] = ..., step: int = ...) -> int: + """ + Return a randomly selected element from ``range(start, stop, step)``. + """ + ... + +_T = TypeVar("_T") + +def choice(seq: Sequence[_T]) -> _T: + """Return a random element from the non-empty sequence ``seq``. If ``seq`` is + empty, raises ``IndexError``. + """ + ... + +def random() -> float: + """Return the next random floating point number in the range [0.0, 1.0)""" + ... + +def uniform(a: float, b: float) -> float: + """ + Return a random floating point number ``N`` such that ``a <= N <= b`` + for ``a <= b`` and ``b <= N <= a`` for ``b < a``. + """ + ... diff --git a/typeshed/stdlib/ustruct.pyi b/typeshed/stdlib/ustruct.pyi new file mode 100644 index 0000000..3453dd2 --- /dev/null +++ b/typeshed/stdlib/ustruct.pyi @@ -0,0 +1,44 @@ +"""pack and unpack primitive data types + +Supported size/byte order prefixes: ``@``, ``<``, ``>``, ``!``. + +Supported format codes: ``b``, ``B``, ``h``, ``H``, ``i``, ``I``, ``l``, +``L``, ``q``, ``Q``, ``s``, ``P``, ``f``, ``d`` (the latter 2 depending +on the floating-point support). + +.. admonition:: Difference to CPython + :class: attention + + Whitespace is not supported in format strings. +""" + +from typing import Any, Tuple, Union + +def calcsize(fmt: str) -> int: + """Return the number of bytes needed to store the given *fmt*.""" + ... + +def pack(fmt: str, v1: Any, *vn: Any) -> bytes: + """Pack the values *v1*, *v2*, ... according to the format string *fmt*. + The return value is a bytes object encoding the values.""" + ... + +def pack_into(fmt: str, buffer: bytearray, offset: int, v1: Any, *vn: Any) -> None: + """Pack the values *v1*, *v2*, ... according to the format string *fmt* + into a *buffer* starting at *offset*. *offset* may be negative to count + from the end of *buffer*. + """ + ... + +def unpack(fmt: str, data: Union[bytes, bytearray]) -> Tuple: + """Unpack from the *data* according to the format string *fmt*. + The return value is a tuple of the unpacked values. + """ + ... + +def unpack_from(fmt: str, buffer: Union[bytes, bytearray], offset: int = 0) -> Tuple: + """Unpack from the *data* starting at *offset* according to the format string + *fmt*. *offset* may be negative to count from the end of *buffer*. The return + value is a tuple of the unpacked values. + """ + ... diff --git a/typeshed/stdlib/usys.pyi b/typeshed/stdlib/usys.pyi new file mode 100644 index 0000000..8e8022b --- /dev/null +++ b/typeshed/stdlib/usys.pyi @@ -0,0 +1,109 @@ +"""system specific functions""" + +from typing import Any, Dict, List, NoReturn, TextIO, Tuple + +def exit(retval: object = ...) -> NoReturn: + """Terminate current program with a given exit code. Underlyingly, this + function raise as `SystemExit` exception. If an argument is given, its + value given as an argument to `SystemExit`. + """ + ... + +def print_exception(exc: Exception, file: TextIO = ...) -> None: + """ + Print exception with a traceback to a file-like object *file* (or + `sys.stdout` by default). + + .. admonition:: Difference to CPython + :class: attention + + This is simplified version of a function which appears in the + ``traceback`` module in CPython. Unlike ``traceback.print_exception()``, + this function takes just exception value instead of exception type, + exception value, and traceback object; *file* argument should be + positional; further arguments are not supported. CPython-compatible + ``traceback`` module can be found in `micropython-lib`. + """ + +argv: List[str] +"""A mutable list of arguments the current program was started with.""" + +byteorder: str +"""The byte order of the system (``"little"`` or ``"big"``).""" + +class _implementation: + name: str + version: Tuple[int, int, int] + +implementation: _implementation +"""Object with information about the current Python implementation. For +MicroPython, it has following attributes: + +* *name* - string "micropython" +* *version* - tuple (major, minor, micro), e.g. (1, 7, 0) + +This object is the recommended way to distinguish MicroPython from other +Python implementations (note that it still may not exist in the very +minimal ports). + +.. admonition:: Difference to CPython + :class: attention + + CPython mandates more attributes for this object, but the actual useful + bare minimum is implemented in MicroPython. +""" + +maxsize: int +""" +Maximum value which a native integer type can hold on the current platform, +or maximum value representable by MicroPython integer type, if it's smaller +than platform max value (that is the case for MicroPython ports without +long int support). + +This attribute is useful for detecting "bitness" of a platform (32-bit vs +64-bit, etc.). It's recommended to not compare this attribute to some +value directly, but instead count number of bits in it:: + +bits = 0 +v = sys.maxsize +while v: + bits += 1 + v >>= 1 +if bits > 32: + # 64-bit (or more) platform + ... +else: + # 32-bit (or less) platform + # Note that on 32-bit platform, value of bits may be less than 32 + # (e.g. 31) due to peculiarities described above, so use "> 16", + # "> 32", "> 64" style of comparisons. +""" + +modules: Dict[str, Any] +"""Dictionary of loaded modules. On some ports, it may not include builtin + modules.""" + +path: List[str] +"""A mutable list of directories to search for imported modules.""" + +platform: str +"""The platform that MicroPython is running on. For OS/RTOS ports, this is +usually an identifier of the OS, e.g. ``"linux"``. For baremetal ports it +is an identifier of a board, e.g. ``"pyboard"`` for the original MicroPython +reference board. It thus can be used to distinguish one board from another. +If you need to check whether your program runs on MicroPython (vs other +Python implementation), use `sys.implementation` instead. +""" + +version: str +"""Python language version that this implementation conforms to, as a string.""" + +version_info: Tuple[int, int, int] +"""Python language version that this implementation conforms to, as a tuple of ints. + +.. admonition:: Difference to CPython + :class: attention + + Only the first three version numbers (major, minor, micro) are supported and + they can be referenced only by index, not by name. +""" diff --git a/typeshed/stdlib/utime.pyi b/typeshed/stdlib/utime.pyi new file mode 100644 index 0000000..4fc0044 --- /dev/null +++ b/typeshed/stdlib/utime.pyi @@ -0,0 +1,114 @@ +""" +The ``utime`` module provides functions for getting the current time and date, +measuring time intervals, and for delays. + +.. note:: + The ``utime`` module is a MicroPython implementation of the standard Python + ``time`` module. It can be imported using both ``import utime`` and + ``import time``, but the module is the same. +""" + +from typing import Union + +def sleep(seconds: Union[int, float]) -> None: + """ + Sleep for the given number of seconds. You can use a floating-point number + to sleep for a fractional number of seconds, or use the + :func:`utime.sleep_ms()` and :func:`utime.sleep_us()` functions. + """ + ... + +def sleep_ms(ms: int) -> None: + """ + Delay for given number of milliseconds, should be positive or 0. + """ + ... + +def sleep_us(us: int) -> None: + """ + Delay for given number of microseconds, should be positive or 0. + """ + ... + +def ticks_ms() -> int: + """ + Returns an increasing millisecond counter with an arbitrary reference point, + that wraps around after some value. + """ + ... + +def ticks_us() -> int: + """ + Just like :func:`utime.ticks_ms()` above, but in microseconds. + """ + ... + +def ticks_add(ticks: int, delta: int) -> int: + """ + Offset ticks value by a given number, which can be either positive or + negative. Given a ticks value, this function allows to calculate ticks + value delta ticks before or after it, following modular-arithmetic + definition of tick values. + + Example: + + .. code-block:: python + + # Find out what ticks value there was 100ms ago + print(ticks_add(time.ticks_ms(), -100)) + + # Calculate deadline for operation and test for it + deadline = ticks_add(time.ticks_ms(), 200) + while ticks_diff(deadline, time.ticks_ms()) > 0: + do_a_little_of_something() + + # Find out TICKS_MAX used by this port + print(ticks_add(0, -1)) + """ + ... + +def ticks_diff(ticks1: int, ticks2: int) -> int: + """ + Measure ticks difference between values returned from + :func:`utime.ticks_ms()` or :func:`ticks_us()` functions, as a signed value + which may wrap around. + + The argument order is the same as for subtraction operator, + ``ticks_diff(ticks1, ticks2)`` has the same meaning as ``ticks1 - ticks2``. + + :func:`utime.ticks_diff()` is designed to accommodate various usage + patterns, among them: + + Polling with timeout. In this case, the order of events is known, and you + will deal only with positive results of :func:`utime.ticks_diff()`: + + .. code-block:: python + + # Wait for GPIO pin to be asserted, but at most 500us + start = time.ticks_us() + while pin.value() == 0: + if time.ticks_diff(time.ticks_us(), start) > 500: + raise TimeoutError + + + Scheduling events. In this case, :func:`utime.ticks_diff()` result may be + negative if an event is overdue: + + + .. code-block:: python + + # This code snippet is not optimized + now = time.ticks_ms() + scheduled_time = task.scheduled_time() + if ticks_diff(scheduled_time, now) > 0: + print("Too early, let's nap") + sleep_ms(ticks_diff(scheduled_time, now)) + task.run() + elif ticks_diff(scheduled_time, now) == 0: + print("Right at time!") + task.run() + elif ticks_diff(scheduled_time, now) < 0: + print("Oops, running late, tell task to run faster!") + task.run(run_faster=true) + """ + ...