Get Started with Skulpt
Getting Started with Skulpt is easy!
- Embed skulpt into your existing webpage or blog
- Add skulpt directly to your HTML for a custom integration
- For even more control, teach Skulpt to import your own custom modules
Need some inspiration for a project? Just want to learn or teach Python? Head over to the Gallery to see how great educational projects are using Skulpt
Embed Skulpt
If you want to embed a nice looking bit of code that your users can edit, Trinket.io can help you with that! You can put together the example on their site, and then generate the code for an iframe that you can embed in your page.
Users can Remix your example and save their work to a free Trinket account.
Use the Share button in the trinket above to get embed code. More information on embeeding trinkets here.
Using Skulpt with HTML
Want the compiled js to include in your site? Everything you need is in this zip: skulpt-dist. After adding skulpt.js
or skulpt-min.js
and skulpt-stdlib.js
to your project, load the Javascript just before the </body> closing tag.
We’re working on getting skulpt onto popular CDNs so you can load them straight from there.
Once your HTML is loading Skulpt, here's a really simple example to get you going. You can copy and paste or grab the code from this gist.
Using Custom Modules
This new feature lets you create and host your own modules for use in Skulpt. The following gist shows how to include one of them in a page.
Customizing modules after import
If you want to customize how a module behaves you can use the onAfterImport
hook. Here is a gist of how the trinket guys do it.
Releases
1.3.0
This is a list of changes implemented with this version. Some are internal and others are part of the skulpt API (if we had one 🙂 ).
python 2 incorrectness: (for those still using python 2 in production)
-
long
- when adding two long objects the result is likely to be an
int
- when adding two long objects the result is likely to be an
-
method
- unbound methods are no longer supported
- The
base
class for all type objects will beobject
even if the base class is not specified
skulpt api
-
Sk.builtin.object.prototype.genericGetAttr
->Sk.generic.getAttr
-
Sk.builtin.object.prototype.genericSetAttr
->Sk.generic.setAttr
-
Sk.builtin.type.typeLookup
removed and replaced bySk.abstr.typeLookup
-
biginter.js
replaced by the jsbi library -
Sk.abstr.inherits
removed - inheritance exclusively dealt with bySk.abstr.setUpInheritance
-
Sk.misceval.objectRepr
returns a js string (previouslySk.builtin.str
) -
Sk.__future__.python3
becomes the default. Those wishing to usepython2
must define this in theSk.configure
object. -
Sk.abstr.binary_op_
,Sk.abstr.binary_iop_
,Sk.abstr.unary_op_
removed - useSk.abstr.numberBinOp
,Sk.abstr.numberInplaceBinOp
,Sk.abstr.numberUnaryOp
instead.
call signatures of builtins
-
new
is required for (almost) all builtin types- 3 exceptions -
Sk.builtin.bool
,Sk.builtin.none
,Sk.builtin.NotImplemented
- These 3 will always return their respective constant(s) and are thus not required to be used as constructors.
- 3 exceptions -
- Restricted parameters for directly accessing a constructor of an
Sk.builtin
type - assertion failures raised in dev mode if
new
is not used - if using in production these error will not be raised. This may be a gotcha for anyone using this version.
type | params | notes |
---|---|---|
Sk.builtin.int_ |
number, JSBI (bigint), string, undefined} |
can also be called with a python object that has nb$int defined |
Sk.builtin.float_ |
number, undefined |
can also be called with a python object that has nb$float defined |
Sk.builtin.complex |
number, number |
|
Sk.builtin.list |
{Array=} |
Array of py objects or can be called with a python iterable |
Sk.builtin.tuple |
{Array=} |
Array of py objects can be called with a python iterable |
Sk.builtin.set |
{Array=} |
Array of py objects or can be called with a python iterable |
Sk.builtin.dict |
{Array=} |
key/value pairs - only python objects |
Sk.builtin.str |
{*} |
|
Sk.builtin.bool |
{*} |
Note that you should only pass a number to the int
javascript constructor if it’s absolute value is less than Number.MAX_SAFE_INTEGER
. Similarly you should only pass a JSBI (bigint)
to the int constructor if it’s absolute value is larger than Number.MAX_SAFE_INTEGER
.
Major changes
- All type objects are now callable using their respective
tp$call
methods inherited fromSk.builtin.type
- All native type objects will require a
tp$new
andtp$init
method (maybe inherited bySk.builtin.object
) - All type objects are javascript instances of
Sk.builtin.type
- All single inherited objects follow javascript inheritance
- All native type objects now have the following and replaces the use of
Sk.builtin.func
for all dunder function/methods.-
wrapper_descriptors
akaslot_wrappers
method_descriptors
classmethod_descriptors
-
getset_descriptors
akaattributes
/member_descriptors
-
-
Sk.builtin.sk_method
is an alternative toSk.builtin.func
and is used by the abovedescriptor
types - mangled names are never passed to the user but instead are an attribute on
Sk.builtin.str
instances as$mangled
-
mappingproxy
added -
$d
removed on all type objects. -
attributes
of a type object now only appear on theprototype
. Previously these appeared on both thetype
object and theprototype
Additions
-
dict
,set
,tuple
are suspendible -
map
,filter
,zip
,reversed
,enumerate
are suspendible -
classmethod
,property
,staticmethod
have native skulpt implementations -
super
can now be unbound see this explanation -
Sk.builtin.func
objects gain aqualname
in compile code - API for building native types
Sk.abstr.buildNativeClass
-
range_iterator
class added -
reverse
iterators added forlist
,dict_views
,range
-
|
operator valid fordict
,dict_keys
,dict_items
-
Counter
has number slots added - python docstrings now work
Sk.abstr.
objectHash
buildNativeClass
buildIteratorClass
setUpBuiltinMro
setUpMethods
setUpGetSets
setUpSlots
setUpClassMethod
setUpBaseInheritance
setUpModuleMethod
checkNoKwargs
checkNoArgs
checkOneArg
checkArgsLen
copyKeywordsToNamedArgs
Sk.generic.
getAttr
setAttr
new
newMethodDef
iterNextWithArray
iterNextWithArrayCheckSize
iterLengthHintWithArrayMethodDef
iterReverseLengthHintMethodDef
getSetDict
Sk.misceval.
-
asIndex
- will return the internal representation of the integer - or undefined if not indexable - could be a number or a bigint (JSBI) -
asIndexOrThrow
- doesasIndex
but throws an error if the number is not indexable - with an optional message parameter. -
asIndexSized
- throws an error if the object is not indexable, returns a Number always, Option to throw an error if the index is larger thanNumber.MAX_SAFE_INTEGER
. This is the goto method for most builtins now. -
Iterator
- a python class that easily wraps an iterator -
arrayFromIterable
- optional canSuspend implementation that returns an array from a python iterator -
iterArray
- likeiterFor
but with an array rather than a python iterator
slotdefs.js
- contains all the information about mapping slots to dunders and vice versa.
slot changes only relevant for those developers and those writing slot functions directly - hopefully very few users
-
mp$length
replaced bysq$length
in the codebase -
sq$ass_item
/sq$ass_slice
replaced withmp$ass_subscript
-
nb$nonzero
replaced withnb$bool
and switch version to py2/py3 takes care of mapping the appropriate dunder method. -
mp$del_subscript
replaced bymp$ass_subscript
(as per Cpython)- deleting vs setting an item is based on the call signature
-
mp$ass_subscript(key, value)
-> set item -
mp$ass_subscript(key)
-> delete item
- If a dunder func is defined on a user defined class then the slot function is guaranteed.
- e.g.
__len__
defined guaranteessq$length
. - A slot function defined by skulpt in this way throws the appropriate errors and converts the return value to the appropriate internal object.
-
sq$length
called internally:__len__
is called usingSk.misceval.callsim(OrSuspend)Array
. - The result is checked to be an
int
and then converted tonumber
sincesq$length
expects anumber
.
- e.g.
-
tp$str
removed from some builtins as per Python 3.8 changes - If
tp$richcompare
is defined - wrapper functionsob$eq
etc are created - this waySk.misceval.richCompareBool
need only check for the existence of anob$*
slot.- in fact - the existence of these slots is guaranteed since they are inherited from
Sk.builtin.object
- in fact - the existence of these slots is guaranteed since they are inherited from
-
tp$mro
/tp$bases
are Js Arrays rather thanSk.builtin.tuple
-
tp$str
and$r
for errors were changed as per Cpython. -
nb$int_
->nb$int
-
nb$lng
->nb$long
-
nb$float_
->nb$float
- return values for certain slot functions have changed
-
tp$hash
- should return a javascript number less thanNumber.MAX_SAFE_INTEGER
can be postive or negative -
nb$index
- should return a javascript number or BigInt (older browsers should be a JSBI BigInt)
-
-
tp$name
was removed from instances ofSk.builtin.func
andSk.buitin.method
in favour of$name
since it’stp$name
should be thetype name
flags - only relevant internally
-
sk$acceptable_as_base_class
used for some type objects -
sk$object
every skulpt object will have this flag. An easy way to determine if you have a skulpt object or a javascript object -
hp$type
all instance ofsk$klass
types -
sk$prototypical
do we need to walk up the MRO or can we just check theprototype
-
sk$builtinBase
the most derived base which is a native skulpt class -
sk$baseClass
builtin classes that are direct children ofobject
other internal changes
- the use of
numPromoteFunc
was removed for performance improvements in the implementation ofSk.asbtr.numberBinOp
- It was performance beneficial to leave the promoting to the respective
nb$
slots -
int
binop slots only deal with instance ofint
-
float
binop slots deal with instances offloat
andint
-
complex
binop slots deal with instances ofcomplex
,float
andint
- It was performance beneficial to leave the promoting to the respective
- since
long
was effectively removed when a number is larger thanNumber.MAX_SAFE_INTEGER
it’s.v
value is aBigInt
. ifBigInt
is not available in the browser then theJSBI
library is used to replicateBigInt
functionality. -
set
andfrozenset
now share much of their implementation -
collections
module rewritten using new api -
itertools
module rewritten using new api - these are now type objects rather than instances ofgenerator
-
operator
module rewritten using new api -
math
module adapted to the new api -
dict
andset
throw errors if the objects change size during iteration as per Cpython.- fully tested
-
Sk.builtin.check*
moved tosrc/check.js
-
number.js
removed -
numtype.js
removed -
seqtype.js
removed -
mp$subscript
should not be called by a js object (see changes inrandom.js
) -
quick$lookup
added todict.prototype
which is a fast way to lookup upstr
keys -
dict.prototype.entries
rather than has values that arearrays
of key value pairs -
object.prototype.tp$hash
will no longer add$savedHash_
to the object - instead it uses a javascript map and assigns objects to a random number less thanNumber.MAX_SAFE_INTEGER
rather than incrementing the hash value each time. -
float.prototype.tp$hash
for integers this will be the same value asSk.builtin.int.prototype.tp$hash
for non integers this will be a random number less thanNumber.MAX_SAFE_INTEGER
. Previously this was the number rounded down - but this creates a lot of collisions.
0.10.0
This latest release contains a lot of goodness.
- You can now inherit from builtin types including Exceptions!
- Major cleanup of numeric types
- Bug fixes for iteration when using subclasses with our without
__getitem__
- Bug fixes and more completeness to lookups of dunder methods
- complex type is added
- brun command added to skulpt for easy access to in-browser debug
- Many Many minor bug fixes.