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
Nateve transpiler developed with python.

Adam Adam is a Nateve Programming Language transpiler developed using Python. Nateve Nateve is a new general domain programming language open source i

Nateve 7 Jan 15, 2022
Change your Windows background with this program safely & easily!

Background_Changer Table of Contents: About the Program Features Requirements Preview Credits Reach Me See Also About the Program: You can change your

Sina.f 0 Jul 14, 2022
Karte der Allgemeinverfügungen zu Schulschließungen oder eingeschränktem Regelbetrieb in Sachsen

SNSZ Karte Datenquelle: Allgemeinverfügungen zu Schulschließungen oder eingeschränktem Regelbetrieb in Sachsen Sächsisches Staatsministerium für Kultu

Jannis Leidel 3 Sep 26, 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
It is a Blender Tool which can convert the Object Data Attributes in face corner to the UVs or Vertex Color.

Blender_ObjectDataAttributesConvertTool It is a Blender Tool which can convert the Object Data Attributes in face corner to the UVs or Vertex Color. D

Takeshi Chō 2 Jan 08, 2022
Ramadhan countdown - Simple daily reminder about upcoming Ramadhan

Ramadhan Countdown Bot Simple bot for displaying daily reminder about Islamic pr

Abdurrahman Shofy Adianto 1 Feb 06, 2022
A C-like hardware description language (HDL) adding high level synthesis(HLS)-like automatic pipelining as a language construct/compiler feature.

██████╗ ██╗██████╗ ███████╗██╗ ██╗███╗ ██╗███████╗ ██████╗ ██╔══██╗██║██╔══██╗██╔════╝██║ ██║████╗ ██║██╔════╝██╔════╝ ██████╔╝██║██████╔╝█

Julian Kemmerer 391 Jan 01, 2023
Simply create JIRA releases based on your github releases

Simply create JIRA releases based on your github releases

8 Jun 17, 2022
creates a batch file that uses adb to auto-install apks into the Windows Subsystem for Android and registers it as the default application to open apks.

wsa-apktool creates a batch file that uses adb to auto-install apks into the Windows Subsystem for Android and registers it as the default application

Aditya Vikram 3 Apr 05, 2022
tetrados is a tool to generate a density of states using the linear tetrahedron method from a band structure.

tetrados tetrados is a tool to generate a density of states using the linear tetrahedron method from a band structure. Currently, only VASP calculatio

Alex Ganose 1 Dec 21, 2021
Multitrack exporter for OP-Z

Underbridge for OP-Z Multitrack exporter Description Exports patterns and projects individual audio tracks to seperate folders for use in your DAW. Py

Thomas Herrmann 71 Dec 25, 2022
SimilarWeb for Team ACT v.0.0.1

SimilarWeb for Team ACT v.0.0.1 This module has been built to provide a better environment specifically for Similarweb in Team ACT. This module itself

Sunkyeong Lee 0 Dec 29, 2021
Displays Christmas-themed ASCII art

Christmas Color Scripts Displays Christmas-themed ASCII art. This was mainly inspired by DistroTube's Shell Color Scripts Screenshots ASCII Shadow Tex

1 Aug 09, 2022
Audio-analytics for music-producers! Automate tedious tasks such as musical scale detection, BPM rate classification and audio file conversion.

Click here to be re-directed to the Beat Inspect Streamlit Web-App You are a music producer? Let's get in touch via LinkedIn Fundamental Analytics for

Stefan Rummer 11 Dec 27, 2022
A Python script to convert your favorite TV series into an Anki deck.

Ankiniser A Python3.8 script to convert your favorite TV series into an Anki deck. How to install? Download the script with git or download it manualy

37 Nov 03, 2022
The program converts Swiss notes into American notes

Informatik-Programmieren Einleitung: Das Programm rechnet Schweizer Noten in das Amerikanische Noten um. Der Benutzer kann seine Note eingeben und der

2 Dec 16, 2021
A maubot plugin to invite users to Matrix rooms according to LDAP groups

LDAP Inviter Bot This is a maubot plugin that invites users to Matrix rooms according to their membership in LDAP groups.

David Mehren 14 Dec 09, 2022
A small C compiler written in Python for learning purposes

A small C compiler written in Python. Generates x64 Intel-format assembly, which is then assembled and linked by nasm and ld.

Scattered Thoughts 3 Oct 22, 2021
En este repositorio realizaré la tarea del laberinto.

Laberinto Perfil de GitHub del autor de este proyecto: @jmedina28 En este repositorio queda resuelta la composición de un laberinto 5x5 con sus muros

Juan Medina 1 Dec 11, 2021
Konomi: Kind and Optimized Next brOadcast watching systeM Infrastructure

Konomi 備考・注意事項 現在 α 版で、まだ実験的なプロダクトです。通常利用には耐えないでしょうし、サポートもできません。 安定しているとは到底言いがたい品質ですが、それでも構わない方のみ導入してください。 使い方などの説明も用意できていないため、自力でトラブルに対処できるエンジニアの方以外に

tsukumi 243 Dec 30, 2022