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
baseclass for all type objects will beobjecteven 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.typeLookupremoved and replaced bySk.abstr.typeLookup -
biginter.jsreplaced by the jsbi library -
Sk.abstr.inheritsremoved - inheritance exclusively dealt with bySk.abstr.setUpInheritance -
Sk.misceval.objectReprreturns a js string (previouslySk.builtin.str) -
Sk.__future__.python3becomes the default. Those wishing to usepython2must define this in theSk.configureobject. -
Sk.abstr.binary_op_,Sk.abstr.binary_iop_,Sk.abstr.unary_op_removed - useSk.abstr.numberBinOp,Sk.abstr.numberInplaceBinOp,Sk.abstr.numberUnaryOpinstead.
call signatures of builtins
-
newis 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.builtintype - assertion failures raised in dev mode if
newis 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$callmethods inherited fromSk.builtin.type - All native type objects will require a
tp$newandtp$initmethod (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.funcfor all dunder function/methods.-
wrapper_descriptorsakaslot_wrappers method_descriptorsclassmethod_descriptors-
getset_descriptorsakaattributes/member_descriptors
-
-
Sk.builtin.sk_methodis an alternative toSk.builtin.funcand is used by the abovedescriptortypes - mangled names are never passed to the user but instead are an attribute on
Sk.builtin.strinstances as$mangled -
mappingproxyadded -
$dremoved on all type objects. -
attributesof a type object now only appear on theprototype. Previously these appeared on both thetypeobject and theprototype
Additions
-
dict,set,tupleare suspendible -
map,filter,zip,reversed,enumerateare suspendible -
classmethod,property,staticmethodhave native skulpt implementations -
supercan now be unbound see this explanation -
Sk.builtin.funcobjects gain aqualnamein compile code - API for building native types
Sk.abstr.buildNativeClass
-
range_iteratorclass added -
reverseiterators added forlist,dict_views,range -
|operator valid fordict,dict_keys,dict_items -
Counterhas number slots added - python docstrings now work
Sk.abstr.
objectHashbuildNativeClassbuildIteratorClasssetUpBuiltinMrosetUpMethodssetUpGetSetssetUpSlotssetUpClassMethodsetUpBaseInheritancesetUpModuleMethodcheckNoKwargscheckNoArgscheckOneArgcheckArgsLencopyKeywordsToNamedArgs
Sk.generic.
getAttrsetAttrnewnewMethodDefiterNextWithArrayiterNextWithArrayCheckSizeiterLengthHintWithArrayMethodDefiterReverseLengthHintMethodDefgetSetDict
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- doesasIndexbut 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- likeiterForbut 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$lengthreplaced bysq$lengthin the codebase -
sq$ass_item/sq$ass_slicereplaced withmp$ass_subscript -
nb$nonzeroreplaced withnb$booland switch version to py2/py3 takes care of mapping the appropriate dunder method. -
mp$del_subscriptreplaced 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$lengthcalled internally:__len__is called usingSk.misceval.callsim(OrSuspend)Array. - The result is checked to be an
intand then converted tonumbersincesq$lengthexpects anumber.
- e.g.
-
tp$strremoved from some builtins as per Python 3.8 changes - If
tp$richcompareis defined - wrapper functionsob$eqetc are created - this waySk.misceval.richCompareBoolneed 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$basesare Js Arrays rather thanSk.builtin.tuple -
tp$strand$rfor 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_INTEGERcan be postive or negative -
nb$index- should return a javascript number or BigInt (older browsers should be a JSBI BigInt)
-
-
tp$namewas removed from instances ofSk.builtin.funcandSk.buitin.methodin favour of$namesince it’stp$nameshould be thetype name
flags - only relevant internally
-
sk$acceptable_as_base_classused for some type objects -
sk$objectevery skulpt object will have this flag. An easy way to determine if you have a skulpt object or a javascript object -
hp$typeall instance ofsk$klasstypes -
sk$prototypicaldo we need to walk up the MRO or can we just check theprototype -
sk$builtinBasethe most derived base which is a native skulpt class -
sk$baseClassbuiltin classes that are direct children ofobject
other internal changes
- the use of
numPromoteFuncwas removed for performance improvements in the implementation ofSk.asbtr.numberBinOp- It was performance beneficial to leave the promoting to the respective
nb$slots -
intbinop slots only deal with instance ofint -
floatbinop slots deal with instances offloatandint -
complexbinop slots deal with instances ofcomplex,floatandint
- It was performance beneficial to leave the promoting to the respective
- since
longwas effectively removed when a number is larger thanNumber.MAX_SAFE_INTEGERit’s.vvalue is aBigInt. ifBigIntis not available in the browser then theJSBIlibrary is used to replicateBigIntfunctionality. -
setandfrozensetnow share much of their implementation -
collectionsmodule rewritten using new api -
itertoolsmodule rewritten using new api - these are now type objects rather than instances ofgenerator -
operatormodule rewritten using new api -
mathmodule adapted to the new api -
dictandsetthrow errors if the objects change size during iteration as per Cpython.- fully tested
-
Sk.builtin.check*moved tosrc/check.js -
number.jsremoved -
numtype.jsremoved -
seqtype.jsremoved -
mp$subscriptshould not be called by a js object (see changes inrandom.js) -
quick$lookupadded todict.prototypewhich is a fast way to lookup upstrkeys -
dict.prototype.entriesrather than has values that arearraysof key value pairs -
object.prototype.tp$hashwill no longer add$savedHash_to the object - instead it uses a javascript map and assigns objects to a random number less thanNumber.MAX_SAFE_INTEGERrather than incrementing the hash value each time. -
float.prototype.tp$hashfor integers this will be the same value asSk.builtin.int.prototype.tp$hashfor 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.