Null safe support for Python

Overview

Null Safe Python

Null safe support for Python.

Installation

pip install nullsafe

Quick Start

Dummy Class

class Dummy:
    pass

Normal Python code:

o = Dummy()

try:
    value = o.inexistent
except AttributeError:
    print("oops")

With nullsafe:

from nullsafe import undefined, _

o = Dummy()

value = _(o).inexistent

if value is undefined:
    print("oops")

Note that if not value and if value == None also works.

Documentation

Basics

There are 5 values importable in nullsafe root:

class NullSafeProxy: (o: T)

Receives an object o on instantiation.

Proxy class for granting nullsafe abilities to an object.

class NullSafe: ()

No argument needed.

Nullish class with with nullsafe abilities. Instances will have a falsy boolean evaluation, equity comparison (==) to None and instance of NullSafe returns True, otherwise False. Identity comparison (is) to None will return False. It also has a __call__ method that always returns undefined.

variable undefined: NullSafe

Instance of Nullsafe, this instance will be returned for all nullish access in a proxied object, enabling identity comparison value is undefined for code clarity.

function nullsafe: (o: T) -> T | NullSafe | NullSafeProxy[T]

Receives an object o as argument.

Helper function that checks if object is nullish and return the proxied object.

return undefined if o is None or undefined, otherwise return the proxied object NullSafeProxy[T].

This function is generic typed ((o: T) -> T), code autocompletions and linters functionalities will remain. Disclaimer: If the object was not typed before proxy, it obviously won't come out typed out of the blue.

function _: (o: T) -> T | NullSafe | NullSafeProxy[T] (alias to nullsafe)

Alias to nullsafe, used for better code clarity.

Implementation

Nullsafe abilities are granted after proxying an object through NullSafeProxy. To proxy an object pass it through _() or nullsafe(). Due to language limitation, the implementation does not follow the "return the first nullish value in chain", instead it "extend undefined (custom nullish value) until the end of chain". Inexistent values of a proxied object and its subsequent values in chain will return undefined.

Import

from nullsafe import undefined, _

Usage

Various ways of using nullsafe.

The examples shown will be using the _ import instead of nullsafe for code clarity. For better understanding, the Javascript equivalents will be shown as comments.

Null safe attribute access

Proxied object doing a possibly AttributeError access.

o = Dummy()

# o.inexistent
assert _(o).inexistent is undefined
assert _(o).inexistent == None   # undefined == None
assert not _(o).inexistent       # bool(undefined) == False

# o.inexistent?.nested
assert _(o).inexistent.nested is undefined

# o.existent.inexistent?.nested
assert _(o.existent).inexistent.nested is undefined

# o.maybe?.inexistent?.nested
assert _(_(o).maybe).inexistent.nested is undefined

# o.inexistent?.inexistcall("anything").inexistent.nested().final
assert _(o).inexistent.inexistcall("anything").inexistent.nested().final is undefined

Null safe item access

Proxied object doing a possibly KeyError access.

o = Dummy() # dict works too !

# o.inexistent
assert _(o)["inexistent"] is undefined
assert _(o)["inexistent"] == None    # undefined == None
assert not _(o)["inexistent"]        # bool(undefined) == False

# o.inexistent?.nested
assert _(o)["inexistent"]["nested"] is undefined

# o.existent.inexistent?.nested
assert _(o["existent"])["inexistent"]["nested"] is undefined

# o.maybe?.inexistent?.nested
assert _(_(o)["maybe"])["inexistent"]["nested"] is undefined

# o.inexistent?.inexistcall("anything").inexistent.nested().final
assert _(o)["inexistent"]["inexistcall"]("anything")["inexistent"]["nested"]()["final"] is undefined

Null safe post evaluation

Possibly None or undefined object doing possibly AttributeError or KeyError access.

Note: This only works if the seeking value is accessible, see limitations

o = Dummy() # dict works too !
o.nay = None

# o.nay?.inexistent
assert _(o.nay).inexistent is undefined
assert _(o.nay).inexistent == None   # undefined == None
assert not _(o.nay).inexistent       # bool(undefined) == False

# o.nay?.inexistent.nested
assert _(o.nay).inexistent.nested is undefined

# o.nay?.inexistent().nested
assert _(o.nay).inexistent().nested is undefined
o = Dummy() # dict works too !
o["nay"] = None

# o.nay?.inexistent
assert _(o["nay"])["inexistent"] is undefined

# o.nay?.inexistent.nested
assert _(o["nay"])["inexistent"]["nested"] is undefined

# o.nay?.inexistent().nested
assert _(o["nay"])["inexistent"]()["nested"] is undefined

Combined usage

Of course you can combine different styles.

assert _(o).inexistent["inexistent"].inexistent.inexistent["inexistent"]["inexistent"] is undefined

Limitations

List of limitations that you may encounter.

undefined behavior

undefined is actually an instance of NullSafe, the actual mechanism used for nullsafe chaining, it cannot self rip the nullsafe functionality when the chain ends (because it doesn't know), so the following instruction is technically correct but probably not the wanted behavior.

val = _(o).inexistent

assert val.another_inexistent is undefined

Post evaluation

In other languages like Javascript, it checks for each item in the chain and return undefined on the first nullish value, which in fact is post-evaluated. This is not possible in python because it raises an AttributeError or KeyError on access attempt, unless it returns None (see one of the available usage), so it must proxy the instance that may contain the attr or key before accessing.

try:
    val = _(o.inexistent).nested # AttributeError: '
   
    ' object has no attribute 'inexistent'
   
except AttributeError:
    assert True
assert _(o).inexistent.nested is undefined

Contributing

Contributions welcomed ! Make sure it passes current tests tho.

You might also like...
You can easily send campaigns, e-marketing have actually account using cash will thank you for using our tools, and you can support our Vodafone Cash +201090788026

*** Welcome User Sorry I Mean Hello Brother ✓ Devolper and Design : Mokhtar Abdelkreem ========================================== You Can Follow Us O

Irrigation Component V4 providing support for a custom card
Irrigation Component V4 providing support for a custom card

Irrigation Component V4 This release sees the delivery of a custom card https://github.com/petergridge/irrigation_card to render the program options s

Library support get vocabulary from MEM

Features: Support scraping the courses in MEM to take the vocabulary Translate the words to your own language Get the IPA for the English course Insta

Kellogg bad | Union good | Support strike funds

KelloggBot Credit to SeanDaBlack for the basis of the script. req.py is selenium python bot. sc.js is a the base of the ios shortcut [COMING SOON] Set

Custom Weapons 3 attribute support for Custom Weapons X

CW3toX Allows use of Custom Weapons 3 attributes in Custom Weapons X. Requiremen

Wordler - A program to support you to solve the wordle puzzles

solve wordle (https://www.powerlanguage.co.uk/wordle) A program to support you t

HatAsm - a HatSploit native powerful assembler and disassembler that provides support for all common architectures

HatAsm - a HatSploit native powerful assembler and disassembler that provides support for all common architectures.

[x]it! support for working with todo and check list files in Sublime Text
[x]it! support for working with todo and check list files in Sublime Text

[x]it! for Sublime Text This Sublime Package provides syntax-highlighting, shortcuts, and auto-completions for [x]it! files. Features Syntax highlight

Todos os exercícios do Curso de Python, do canal Curso em Vídeo, resolvidos em Python, Javascript, Java, C++, C# e mais...
Todos os exercícios do Curso de Python, do canal Curso em Vídeo, resolvidos em Python, Javascript, Java, C++, C# e mais...

Exercícios - CeV Oferecido por Linguagens utilizadas atualmente O que vai encontrar aqui? 👀 Esse repositório é dedicado a armazenar todos os enunciad

Releases(v0.2.1)
Owner
Paaksing
Paaksing
Get a list of content on your Netflix My List that is expiring in the next month or two.

Netflix My List Expiring Movies Annoyed at Netflix for taking away your movies? Now you don't have to be! Installation instructions Install selenium C

24 Aug 06, 2022
A Notifier Program that Notifies you to relax your eyes Every 15 Minutes👀

Every 15 Minutes is an application that is used to Notify you to Relax your eyes Every 15 Minutes, This is fully made with Python and also with the us

FSP Gang s' YT 2 Nov 11, 2021
Always fill your package requirements without the user having to do anything! Simple and easy!

WSL Should now work always-fill-reqs-python3 Always fill your package requirements without the user having to do anything! Simple and easy! Supported

Hashm 7 Jan 19, 2022
Mangá downloader (para leitura offline) voltado para sites e scans brasileiros.

yonde! yonde! (読んで!) é um mangá downloader (para leitura offline) voltado para sites e scans brasileiros. Também permite que você converta os capítulo

Yonde 8 Nov 28, 2021
A light library to build tiny websites

A light library to build tiny websites

BT.Q 1 Dec 23, 2021
mrcal is a generic toolkit to solve calibration and SFM-like problems originating at NASA/JPL

mrcal is a generic toolkit to solve calibration and SFM-like problems originating at NASA/JPL. Functionality related to these problems is exposed as a set of C and Python libraries and some commandli

Dima Kogan 102 Dec 23, 2022
Skull shaped MOSFET cells for the Efabless's 130nm process

SkullFET Skull shaped MOSFET cells for the Efabless's 130nm process List of cells Inverter Copyright (C) 2021 Uri Shaked

Wokwi 3 Dec 14, 2022
Tools Elit Adalah Sebuah Script Crack Yang Wajib Tap Yes...

Tools Elit Adalah Sebuah Script Crack Yang Wajib Tap Yes...

Risky [ Zero Tow ] 10 Apr 07, 2022
Tips that improve your life in one way or another

Tips that improve your life in one way or another. This software downloads life tips from reddit.com/r/LifeProTips and tweet the most upvoted tips on Twitter.

Burak Tokman 2 Aug 04, 2022
Hypothesis strategies for generating Python programs, something like CSmith

hypothesmith Hypothesis strategies for generating Python programs, something like CSmith. This is definitely pre-alpha, but if you want to play with i

Zac Hatfield-Dodds 73 Dec 14, 2022
TimeWizard - A script that generates every single Time Wizard EDOPRO lflist possible

EDOPRO F&L list generator This project is just a script that generates every sin

Diamond Dude 2 Sep 28, 2022
Structural basis for solubility in protein expression systems

Structural basis for solubility in protein expression systems Large-scale protein production for biotechnology and biopharmaceutical applications rely

ProteinQure 16 Aug 18, 2022
App to get data from popular polish pages with job offers

Job board parser I written simple app to get me data from popular pages with job offers, because I wanted to knew immidietly if there is some new offe

0 Jan 04, 2022
💘 Write any Python with 9 Characters: e,x,c,h,r,(,+,1,)

💘 PyFuck exchr(+1) PyFuck is a strange playful code. It uses only nine different characters to write Python3 code. Inspired by aemkei/jsfuck Example

Satoki 10 Dec 25, 2022
Anki Cards for the HSK vocabulary Chinese-German

Anki-HanyuShuipingKaoshi Anki Cards for the HSK vocabulary Chinese-German Das Deck baut auf folgenden Quellen auf: China Endecken Wortschatz von wohok

1 Jan 07, 2022
Replit theme sync; Github theme sync but in Replit.

This is a Replit theme sync, basically meaning that it keeps track of the current time (which may need to be edited later on), and if the time passes morning, afternoon, etc, the theme switches. The

Glitch 8 Jun 25, 2022
Tc-python - A Python script to receive message from a twitch chat

Twitch-Chat 📜 I did a script in Python to receive messages from a twitch chat.

miyucode 2 May 31, 2022
a package that provides a marketstrategy for whitelisting on golem

filterms a package that provides a marketstrategy for whitelisting on golem watching requestor logs distribute 10 tasks asynchronously is fun. but you

KJM 3 Aug 03, 2022
A Python script to parse Fortinet products serial numbers, and detect the associated model and version.

ParseFortinetSerialNumber A Python script to parse Fortinet products serial numbers, and detect the associated model and version. Example $ ./ParseFor

Podalirius 10 Oct 28, 2022
A python package for bitclout.

BitClout.py A python package for bitclout. Developed by ItsAditya Run pip install bitclout to install the module! Examples of How To Use BitClout.py G

ItsAditya 9 Dec 31, 2021