Feeds
Ned Batchelder: Testing some tidbits
I posted a Python tidbit about checking if a string consists entirely of zeros and ones:
I got a bunch of replies suggesting other ways. I wanted to post those, but I also wanted to check if they were right. A classic testing structure would have required putting them all in functions, etc, which I didn’t want to bother with.
So I cobbled together a test harness for them (also in a gist if you want):
GOOD = ["",
"0",
"1",
"000000000000000000",
"111111111111111111",
"101000100011110101010000101010101001001010101",
]
BAD = [
"x",
"nedbat",
"x000000000000000000000000000000000000",
"111111111111111111111111111111111111x",
"".join(chr(i) for i in range(10000)),
]
TESTS = """
# The original checks
all(c in "01" for c in s)
set(s).issubset({"0", "1"})
set(s) <= {"0", "1"}
re.fullmatch(r"[01]*", s)
s.strip("01") == ""
not s.strip("01")
# Using min/max
"0" <= min(s or "0") <= max(s or "1") <= "1"
not s or (min(s) in "01" and max(s) in "01")
((ss := sorted(s or "0")) and ss[0] in "01" and ss[-1] in "01")
# Using counting
s.count("0") + s.count("1") == len(s)
(not (ctr := Counter(s)) or (ctr["0"] + ctr["1"] == len(s)))
# Using numeric tests
all(97*c - c*c > 2351 for c in s.encode())
max((abs(ord(c) - 48.5) for c in "0"+s)) < 1
all(map(lambda x: (ord(x) ^ 48) < 2, s))
# Removing all the 0 and 1
re.sub(r"[01]", "", s) == ""
len((s).translate(str.maketrans("", "", "01"))) == 0
len((s).replace("0", "").replace("1", "")) == 0
"".join(("1".join((s).split("0"))).split("1")) == ""
# A few more for good measure
set(s + "01") == set("01")
not (set(s) - set("01"))
not any(filter(lambda x: x not in {"0", "1"}, s))
all(map(lambda x: x in "01", s))
"""
import re
from collections import Counter
from inspect import cleandoc
g = {
"re": re,
"Counter": Counter,
}
for test in cleandoc(TESTS).splitlines():
test = test.partition("#")[0]
if not test:
continue
for ss, expected in [(GOOD, True), (BAD, False)]:
for s in ss:
result = eval(test, {"s": s} | g)
if bool(result) != expected:
print("OOPS:")
print(f" {s = }")
print(f" {test}")
print(f" {expected = }")
It’s a good thing I did this because a few of the suggestions needed adjusting, especially for dealing with the empty string. But now they all work, and are checked!
BTW, if you prefer Mastodon to BlueSky, the posts are there too: first and second.
LostCarPark Drupal Blog: Drupal Advent Calendar day 4 - Drupal.org
Today Tim Lehnen from the Drupal Association joins us to talk about some of the changes taking place on the Drupal.org website as part of Starshot.
For day 4 of the Drupal Advent calendar, it’s a familiar face: Drupal.org! When we say “Come for the code, stay for the community!” Drupal.org is where we welcome everyone to join us. Sure, you can find all the code, extensions, and documentation you need here, but Drupal.org is so much more. It’s the place where one of the greatest communities in open source gathers to communicate, collaborate, and celebrate.
Drupal.org is also a part of Drupal…
TagsDjango Weblog: Help us make it happen ❤️
And just like that, 2024 is almost over! If your finances allow, donate to the Django Software Foundation to support the long-term future of Django.
84%Of our US $200,000.00 goal for 2024, as of December 4th, 2024, we are at:
- 83.6% funded
- $167,272.85 donated
- Official merchandise store - Buy official t-shirts, accessories, and more to support Django.
- Sponsor Django via GitHub Sponsors.
- Benevity Workplace Giving Program - If your employer participates, you can make donations to the DSF via payroll deduction.
Our main focus is direct support of Django's developers. This means:
- Organizing and funding development sprints so that Django's developers can meet in person.
- Helping key developers attend these sprints and other community events by covering travel expenses to official Django events.
- Providing financial assistance to community development and outreach projects such as Django Girls.
- Providing financial assistance to individuals so they can attend major conferences and events.
- Funding the Django Fellowship program, which provides full-time staff to perform community management tasks in the Django community.
Still curious? See our Frequently Asked Questions about donations.
FSF Blogs: The Licensing and Compliance Team is fighting for freedom and we need your help
The Licensing and Compliance Team is fighting for freedom and we need your help
Kushal Das: Basedpyright and neovim
Basedpyright is a fork of pyright with various type checking improvements, improved vscode support and pylance features built into the language server. It has a list of benefits over Pyright.
In case you want to use that inside of neovim using Mason, you will have to remember to have the configuration inside of a settings key. The following is from my setup.
basedpyright = { settings = { basedpyright = { analysis = { diagnosticMode = 'openFilesOnly', typeCheckingMode = 'basic', capabilities = capabilities, useLibraryCodeForTypes = true, diagnosticSeverityOverrides = { autoSearchPaths = true, enableTypeIgnoreComments = false, reportGeneralTypeIssues = 'none', reportArgumentType = 'none', reportUnknownMemberType = 'none', reportAssignmentType = 'none', }, }, }, }, },Struggled for a few hours to fix this couple of days ago.
PyCoder’s Weekly: Issue #658 (Dec. 3, 2024)
#658 – DECEMBER 3, 2024
View in Browser »
Performance tuning in the context of Django applications is the practice of enhancing both the efficiency and effectiveness of your web project to optimize its runtime behavior. This article tells you a lot of what you need to know.
LOADFORGE.COM
Python’s pathlib module is the tool to use for working with file paths. This post contains pathlib quick reference tables and examples.
TREY HUNNER
ZenRows handles all anti-bot bypass for you, from rotating proxies and headless browsers to CAPTCHAs and AI. Get a complete web scraping toolkit to extract all the data you need with a single API call. Try ZenRows now for free →
ZENROWS sponsor
Learn how Python Poetry can help you start new projects, maintain existing ones, and master dependency management.
REAL PYTHON course
This annual tradition is a series of small programming puzzles that can be completed in any programming language.
ADVENTOFCODE.COM
With most software following agile methodologies, it’s essential to have robust DevOps systems in place to manage, maintain, and automate common tasks with a continually changing codebase. By using GitHub Actions, you can automate your workflows efficiently, especially for Python projects.
REAL PYTHON
Textual is a great Python package for creating a lightweight, powerful, text-based user interface. Debugging TUIs can be a challenge though as you no longer can use print() and the application may not even run in your IDE’s terminal interface. This post talks about how to debug a TUI.
MIKE DRISCOLL
What are common issues with using notebooks for Python development? How do you know the current state, share reproducible results, or create interactive applications? This week on the show, we speak with Akshay Agrawal about the open-source reactive marimo notebook for Python.
REAL PYTHON podcast
Python’s initial flexibility in packaging with the executable setup.py has meant that people have come to expect this power. In this post Armin argues that if constraints had been there in the first place we’d be in a better place now.
ARMIN RONACHER
Open Database Connectivity (ODBC) is used to connect to various databases. This article aims to help you understand ODBC better by implementing database communications from scratch only using Python.
PRESTON BLACKBURN • Shared by Preston Blackburn
In the past week Brett has had two different people tell him what the PSF Conduct Working Group did, and both were wrong. This post tries to correct what might be common misconceptions.
BRETT CANNON
Pyxel is a Rust based framework for building retro games that comes with a Python API wrapper. This step-by-step tutorial shows you how to do some basic sprite animation to get started.
MATHIEU LECARME
Formatting and concatenating query result columns on the PostgreSQL side and then parsing them in Python might sometimes be faster than fetching the columns as separate values.
ALIAKSEI YALETSKI • Shared by Tiendil
“Improve the performance of your Django application by understanding, testing, and implementing some common optimization techniques.”
SANKET RAI
Continuous Integration (CI) is key to rapid deployment of new features. This post gives you ten rules to consider when doing CI.
KRISTINA NIKOLOVA
CROCOFACTORY.DEV • Shared by Alexey
QodoAI Cover-Agent: AI Tool for Automated Test Generation Peek: Like print, but EasySALABIM.ORG • Shared by Ruud van der Ham
pyvista: 3D Plotting and Mesh Analysis python-fire: Automatically Generate Command Line Interfaces Events Weekly Real Python Office Hours Q&A (Virtual) December 4, 2024
REALPYTHON.COM
December 4 to December 6, 2024
PYCON.OR.TZ
December 4 to December 6, 2024
HAMPLUSTECH.COM
December 5, 2024
MEETUP.COM
December 5, 2024
SYPY.ORG
December 7, 2024
MEETUP.COM
Happy Pythoning!
This was PyCoder’s Weekly Issue #658.
View in Browser »
[ Subscribe to 🐍 PyCoder’s Weekly 💌 – Get the best Python news, articles, and tutorials delivered to your inbox once a week >> Click here to learn more ]
Python Insider: Python 3.13.1, 3.12.8, 3.11.11, 3.10.16 and 3.9.21 are now available
Another big release day! Python 3.13.1 and 3.12.8 were regularly scheduled releases, but they do contain a few security fixes. That makes it a nice time to release the security-fix-only versions too, so everything is as secure as we can make it.
Python 3.13.1Python 3.13’s first maintenance release. My child is all growed up now, I guess! Almost 400 bugfixes, build improvements and documentation changes went in since 3.13.0, making this the very best Python release to date.
https://www.python.org/downloads/release/python-3131/
Python 3.12.8Python 3.12 might be slowly reaching middle age, but still received over 250 bugfixes, build improvements and documentation changes since 3.12.7.
https://www.python.org/downloads/release/python-3128/Python 3.11.11
I know it’s probably hard to hear, but this is the second security-only release of Python 3.11. Yes, really! Oh yes, I know, I know, but it’s true! Only 11 commits went in since 3.11.10.
https://www.python.org/downloads/release/python-31111/Python 3.10.16
Python 3.10 received a total of 14 commits since 3.10.15. Why more than 3.11? Because it needed a little bit of extra attention to keep working with current GitHub practices, I guess.
https://www.python.org/downloads/release/python-31016/Python 3.9.21
Python 3.9 isn’t quite ready for pasture yet, as it’s set to receive security fixes for at least another 10 months. Very similarly to 3.10, it received 14 commits since 3.9.20.
https://www.python.org/downloads/release/python-3921/Stay safe and upgrade!
As always, upgrading is highly recommended to all users of affected versions.
Enjoy the new releasesThanks to all of the many volunteers who help make Python Development and these releases possible! Please consider supporting our efforts by volunteering yourself or through organization contributions to the Python Software Foundation.
Regards from your tireless, tireless release team,
Thomas Wouters
Ned Deily
Steve Dower
Pablo Galindo Salgado
Łukasz Langa
Driving Open Source forward: make your impact in 2025
Our work thrives because of a passionate community dedicated to Open Source values. From advancing initiatives like the Open Source AI Definition to addressing challenges in licensing and policy, collaboration has always been our driving force.
While 2024 brought significant progress, the challenges ahead demand even greater collective action. As we look to 2025, your support will be pivotal in scaling our efforts.
We’ll continue serving as the steward of the Open Source Definition, protecting the Open Source principles and maintaining a list of OSI Approved Licenses.
We’ll continue monitoring policy and standards setting organizations, supporting legislators and policy makers, educating them about the Open Source ecosystem, its role in innovation and its value for an open future.
We’ll continue leading the conversation on Open Source AI, as we’ll need to keep on driving the discussion around data and write position papers to educate legislators in the US, in the EU, and around the world.
And finally, we’ll continue supporting Open Source business practice, helping developers and entrepreneurs to unlock the permissionless innovation enabled by Open Source software.
Join us as a supporting member or, if your organization benefits from Open Source, consider becoming a sponsor. Together, we can protect and expand the freedoms that make Open Source possible—for everyone.
Stefano Maffulli
Executive Director, OSI
I hold weekly office hours on Fridays with OSI members: book time if you want to chat about OSI’s activities, if you want to volunteer or have suggestions.
News from the OSI Celebrating 5 years at the Open Source Initiative: a journey of growth, challenges, and community engagementNick Vidal, community manager at the OSI, shares his story about working at the organization. This isn’t just a story about his career—it’s about the evolution of Open Source, the incredible people he worked with, and the values they’ve championed.
Other highlights:
- Improving Open Source security with the new GitHub Secure Open Source Fund
- Highlights from the Digital Public Goods Alliance Annual Members Meeting 2024
- Open Data and Open Source AI: Charting a course to get more of both
- The Open Source Initiative and the Eclipse Foundation to Collaborate on Shaping Open Source AI (OSAI) Public Policy
- ClearlyDefined v2.0 adds support for LicenseRefs
Article from Time Magazine
The distinction between ‘open’ and ‘closed’ AI models is not as simple as it might appear. While Meta describes its Llama models as open-source, it doesn’t meet the new definition published last month by the Open Source Initiative, which has historically set the industry standard for what constitutes open source.
Other highlights:
- Ai2 releases new language models competitive with Meta’s Llama (TechCrunch)
- AI2 closes the gap between closed-source and open-source post-training (VentureBeat)
- Women leading the charge in open source AI (Capacity Media)
- A battle is raging over the definition of open-source AI (The Economist)
- The best open-source AI models: All your free-to-use options explained (ZDNet)
- Read all press mentions from this past month
News from OSI affiliates:
- Eclipse Foundation: The Open Source Initiative and the Eclipse Foundation to Collaborate on Shaping Open Source AI (OSAI) Public Policy
- DPGA, ITU: Advancing Open Source AI: Definitions, Standards, and Global Implementation for a Sustainable Future
- Apache Software Foundation: The Apache Software Foundation Welcomes a New President
- Linux Foundation: Jim Zemlin, ‘head janitor of open source,’ marks 20 years at Linux Foundation
- Mozilla Foundation: Firefox 1.0 Released 20 Years Ago
- DPGA: Open source key to exchanging best practices in digital government
The State of Open Source Survey
In collaboration with the Eclipse Foundation and Open Source Initiative (OSI).
JobsLead OSI’s public policy agenda and education.
EventsUpcoming events:
- Open Source Experience (December 4-5 – Paris)
- KubeCon + CloudNativeCon India (December 11-12, 2024 – Delhi)
- Deep Dive into the Open Source AI Definition v1.0 (December 12, 2024 – online)
- EU Open Source Policy Summit (January 31, 2025 – Brussels)
- FOSDEM (February 1-2, 2025 – Brussels)
CFPs:
- PyCon US 2025: the Python Software Foundation kicks off Website, CfP, and Sponsorship!
- Automattic
- Sentry
- Cisco
- GitHub
Interested in sponsoring, or partnering with, the OSI? Please see our Sponsorship Prospectus and our Annual Report. We also have a dedicated prospectus for the Deep Dive: Defining Open Source AI. Please contact the OSI to find out more about how your company can promote open source development, communities and software.
Get to vote for the OSI Board by becoming a memberLet’s build a world where knowledge is freely shared, ideas are nurtured, and innovation knows no bounds!
FSF Blogs: Free Software Supporter -- Issue 200, December 2024
Free Software Supporter -- Issue 200, December 2024
FSF Blogs: November GNU spotlight with Amin Bandali
November GNU spotlight with Amin Bandali
Freelock Blog: Automatically show this month and next month in a perpetual calendar
One of our clients is Programming Librarian, a site for librarians to plan educational programs. Programs, like many events, are often seasonal, oriented around holidays and seasonal activities.
The site has a block for each month of the year, containing content for that month. It has a custom field for the month number.
Matt Glaman: The Web APIs powering the Drupal CMS trial experience
This blog expands on my DrupalCon Barcelona talk, which I managed to squeeze into a twenty-minute session slot. You can download a copy of my slides. Unfortunately, I could not dedicate enough time to the project and stepped down as the trial track lead. The Drupal CMS trial is no longer based on my WebAssembly work, and an ongoing process is being conducted to provide an official demo.
Real Python: Handling or Preventing Errors in Python: LBYL vs EAFP
Dealing with errors and exceptional situations is a common requirement in programming. You can either prevent errors before they happen or handle errors after they’ve happened. In general, you’ll have two coding styles matching these strategies: look before you leap (LBYL), and easier to ask forgiveness than permission (EAFP), respectively. In this video course, you’ll dive into the questions and considerations surrounding LBYL vs EAFP in Python.
By learning about Python’s LBYL and EAFP coding styles, you’ll be able to decide which strategy and coding style to use when you’re dealing with errors in your code.
In this video course, you’ll learn how to:
- Use the LBYL and EAFP styles in your Python code
- Understand the pros and cons of LBYL vs EAFP
- Decide when to use either LBYL or EAFP
[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]
Improving Open Source security with the new GitHub Secure Open Source Fund
The Open Source community underpins much of today’s software innovation, but with this power comes responsibility. Security vulnerabilities, unclear licensing, and a lack of transparency in software components pose significant risks to software supply chains. Recognizing this challenge, GitHub recently announced the GitHub Secure Open Source Fund—a transformative initiative aimed at bolstering the security and sustainability of Open Source projects.
What is the Secure Open Source Fund?Launched with a $1.25 million commitment from partners, the GitHub Secure Open Source Fund is designed to address a critical issue: the often-overlooked necessity of security for widely-used Open Source projects. The fund not only provides financial support to project maintainers but also delivers a comprehensive suite of resources, including but-not-limited-to:
- Hands-on security training: A three-week program offering mentorship, workshops, and expert guidance.
- Community engagement: Opportunities to connect with GitHub’s Security Lab, sponsors, and other maintainers.
- Funding milestones: $10,000 per project, tied to achieving key security objectives.
The program’s cohort-based approach fosters collaboration and equips maintainers with the skills, networking, and funding to enhance the security of their projects sustainably.
Why this mattersThe success of Open Source hinges on its trustworthiness. For developers and organizations, the ability to confidently adopt and integrate Open Source projects is paramount. However, without sufficient security measures and transparency, these projects risk introducing vulnerabilities into the software supply chain. GitHub’s Secure Open Source Fund directly tackles this issue by empowering maintainers with the knowledge, community, and funding to make their projects secure and reliable.
Building trust through transparencyThe GitHub Secure Open Source Fund aligns with the global push for greater transparency and resilience in software supply chains between creators and consumers of Open Source software. Its focus on security addresses growing concerns highlighted by regulations such as the EU’s Cyber Resilience Act and US Cyber and Infrastructure Security Agency (CISA). By providing maintainers vital funding to prioritize focused-time and with resources to identify and address vulnerabilities, the program strengthens the foundation of Open Source ecosystems.
GitHub has taken an ecosystem-wide approach, where resources and security go hand in hand. The Open Source Initiative (OSI) was invited to become a launch ecosystem partner, and we hope to contribute with valuable input, feedback, and ideas along with other community members. One of our projects, ClearlyDefined, helps organizations to manage SBOMs at scale for each stage on the supply chain by providing easy access to accurate licensing metadata for Open Source components. Together, we hope to foster greater transparency and security for the entire supply chain.
GitHub Secure Open Source Fund Ecosystem Partners A call to action for the Open Source communityAs GitHub leads the charge with its Secure Open Source Fund, it’s crucial for the broader community to step up. Here’s how you can get involved:
- Learn more about security: Gain access to workshops, group sessions, and mentorship.
- Maximize transparency: Adopt tools like ClearlyDefined to ensure clear metadata for your components.
- Advocate for funding: Support initiatives that prioritize security, whether through sponsorship or advocacy.
Together, we can create a safer, more transparent, and more sustainable Open Source ecosystem.
To learn more about GitHub’s Secure Open Source Fund and apply, visit their official program page and announcement.
Let’s work collectively to secure the software supply chains that power innovation worldwide.
GitHub Secure Open Source Fund SponsorsMetadrop: A content manager on steroids: combine Drupal with AI to create content efficiently
Nowadays, artificial intelligence (AI) has become a powerful tool to enhance the process of creating and managing digital content. Drupal, known for its flexibility and robustness as a content management system (CMS), has already started to integrate this new technology, adding exceptional capabilities for generating and improving content.
In this detailed guide, as a showcase, we will demonstrate how to install and configure the modules AI (Artificial Intelligence) and Image Genie AI in Drupal, the first to integrate AI with CKEditor, thereby improving its editing capabilities, such as text generation, tone alterations, or translations, and the second to generate images, enabling the creation of complete content , quickly and efficiently.
It is worth mentioning that these modules are currently in development phase, so their use in production is currently discouraged.
Prerequisites…LostCarPark Drupal Blog: Drupal Advent Calendar day 3 - Contact Form
Today we’re looking at a fairly simple addition to Starshot, but one that can add a lot of power to a site.
While the default Drupal install provides a contact form, it does it through the rather basic “contact” module, that is built into Drupal Core. This has a lot of limitations, and many people prefer to use the more powerful “Webform” module.
Providing this in Drupal CMS saves the somewhat tedious process of adding a contact form to each Drupal installation. It also adds a Webform contact form in a more standard way, so sites are more likely to follow a consistent pattern when adding…
TagsRuss Allbery: Review: Astrid Parker Doesn't Fail
Review: Astrid Parker Doesn't Fail, by Ashley Herring Blake
Series: Bright Falls #2 Publisher: Berkley Romance Copyright: November 2022 ISBN: 0-593-33644-5 Format: Kindle Pages: 365Astrid Parker Doesn't Fail is a sapphic romance novel and a sequel to Delilah Green Doesn't Care. This is a romance style of sequel, which means that it spoils the previous book but involves a different set of protagonists, one of whom was a supporting character in the previous novel.
I suppose the title is a minor spoiler for Delilah Green Doesn't Care, but not one that really matters.
Astrid Parker's interior design business is in trouble. The small town of Bright Falls doesn't generate a lot of business, and there are limits to how many dentist office renovations that she's willing to do. The Everwood Inn is her big break: Pru Everwood has finally agreed to remodel and, even better, Innside America wants to feature the project. The show always works with local designers, and that means Astrid. National TV exposure is just what she needs to turn her business around and avoid an unpleasant confrontation with her domineering, perfectionist mother.
Jordan Everwood is an out-of-work carpenter and professional fuck-up. Ever since she lost her wife, nothing has gone right either inside or outside of her head. Now her grandmother is renovating the favorite place of her childhood, and her novelist brother had the bright idea of bringing her to Bright Falls to help with the carpentry work. The remodel and the HGTV show are the last chance for the inn to stay in business and stay in the family, and Jordan is terrified that she's going to fuck that up too. And then she dumps coffee all over the expensive dress of a furious woman in a designer dress because she wasn't watching where she was going, and that woman turns out to be the designer of the Everwood Inn renovation. A design that Jordan absolutely loathes.
The reader met Astrid in Delilah Green Doesn't Care (which you definitely want to read first). She's a bit better than she was there, but she's still uptight and unhappy and determined not to think too hard about why. When Jordan spills coffee down her favorite dress in their first encounter, shattering her fragile professional calm, it's not a meet-cute. Astrid is awful to her. Her subsequent regret, combined with immediately having to work with her and the degree to which she finds Jordan surprisingly attractive (surprising in part because Astrid thinks she's straight), slowly crack open Astrid's too-controlled life.
This book was, once again, just compulsively readable. I read most of it the same day that I started it, staying up much too late, and then finished it the next day. It also once again made me laugh in delight at multiple points. I am a sucker for stories about someone learning how to become a better person, particularly when it involves a release of anxiety, and oh my does Blake ever deliver on that. Jordan's arc is more straightforward than Astrid's — she just needs to get her confidence back — but her backstory is a lot more complex than it first appears, including a morally ambiguous character who I would hate in person but who I admired as a deft and tricky bit of characterization.
The characters from Delilah Green Doesn't Care of course play a significant role. Delilah in particular is just as much of a delight here as she was in the first book, and I enjoyed seeing the development of her relationship with her step-sister. But the new characters, both the HGTV film crew and the Everwoods, are also great. I think Blake has a real knack for memorable, distinct supporting characters that add a lot of depth to the main romance plot.
I thought this book was substantially more sex-forward than Delilah Green Doesn't Care, with some lust at first or second sight, a bit more physical description of bodies, and an extended section in the middle of the book that's mostly about sex. If this is or is not your thing in romance novels, you may have a different reaction to this book than the previous one.
There is, unfortunately, another third-act break-up, and this one annoyed me more than the one in Delilah Green Doesn't Care because it felt more unnecessary and openly self-destructive. The characters felt like they were headed towards a more sensible and less dramatic resolution, and then that plot twist caught me by surprise in an unpleasant way. After two books, I'm getting the sense that Blake has a preferred plot arc, at least in this series, and I wish she'd varied the story structure a bit more. Still, the third-act conflict was somewhat believable and the resolution was satisfying enough to salvage it.
If it weren't for some sour feelings about the shape of that plot climax, I would have said that I liked this book even better than Delilah Green Doesn't Care, and that's a high bar. This series is great, and I will definitely be reading the third one. I'm going to be curious how that goes since it's about Iris, who so far has worked better for me as a supporting character than a protagonist. But Blake has delivered compulsively readable and thoroughly enjoyable books twice now, so I'm definitely here for the duration.
If you like this sort of thing, I highly recommend this whole series.
Followed by Iris Kelly Doesn't Date in the romance series sense, but as before this book is a complete story with a satisfying ending.
Rating: 9 out of 10