<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Martin Vielsmaier</title>
    <description>The latest articles on DEV Community by Martin Vielsmaier (@moser).</description>
    <link>https://dev.to/moser</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F270522%2Fe616d2e1-d1be-48d0-99dc-0b88abb91212.jpeg</url>
      <title>DEV Community: Martin Vielsmaier</title>
      <link>https://dev.to/moser</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/moser"/>
    <language>en</language>
    <item>
      <title>SQLAlchemy: Prevent implicit cross join</title>
      <dc:creator>Martin Vielsmaier</dc:creator>
      <pubDate>Wed, 01 Jan 2020 23:00:00 +0000</pubDate>
      <link>https://dev.to/moser/sqlalchemy-prevent-implicit-cross-join-5g5a</link>
      <guid>https://dev.to/moser/sqlalchemy-prevent-implicit-cross-join-5g5a</guid>
      <description>&lt;p&gt;I really like to create SQL queries using SQLAlchemy’s explicit and declarative API. When using this instead of raw strings, roughly half of errors I tend to introduce are caught before even sending the query.&lt;/p&gt;

&lt;p&gt;Here is an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import sqlalchemy as sa

metadata = sa.MetaData()
a = sa.Table(
    "a",
    metadata,
    sa.Column("a_id", sa.Integer, primary_key=True, autoincrement=True),
    sa.Column("name", sa.String),
)
b = sa.Table(
    "b",
    metadata,
    sa.Column("b_id", sa.Integer, primary_key=True, autoincrement=True),
    sa.Column("a_id", sa.Integer, sa.ForeignKey(a.c.a_id)),
)

def create_select(additional_filters):
    return sa.select([a], whereclause=sa.and_(*additional_filters))

print(create_select([a.c.name == 'Foo']))
# SELECT a.a_id, a.name
# FROM a
# WHERE a.name = :name_1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;A huge advantage over dealing with string queries is that you can create different parts of the query on their own and combine them. In the example I create the &lt;code&gt;SELECT&lt;/code&gt; statements in a central place and allow to pass in parts of the where clause.&lt;/p&gt;

&lt;p&gt;Unfortunately, this pattern has a dangerous property: It will implicitly add a&lt;code&gt;CROSS JOIN&lt;/code&gt; when you pass a filter expression that contains a column from a table that is not part of the select statement already.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;print(create_select([a.c.name == 'Foo', b.c.b_id == 1]))
# SELECT a.a_id, a.name
# FROM a, b
# WHERE a.name = :name_1 AND b.b_id = :b_id_1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;On small tables this will just create an unexpected result set, but when the involved tables are large this query might well exhaust the DB server’s resources. The concrete problem can be fixed by adding a join to all the tables that should be allowed in the filters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def create_select_corrected(additional_filters):
    return sa.select([a], from_obj=a.join(b), whereclause=sa.and_(*additional_filters))
print(create_select_corrected([a.c.name == 'Foo', b.c.b_id == 1]))
# SELECT a.a_id, a.name
# FROM a JOIN b ON a.a_id = b.a_id
# WHERE a.name = :name_1 AND b.b_id = :b_id_1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;A more abstract problem is that we can create queries that will lead to unexpected results without noticing. A good but pretty expensive solution would be to validate the parts that are passed in. Depending on how variable the input can be, I would go for this solution. But in other cases it’s just myself using my query construction logic in new ways. So I prefer a cheaper solution that makes me aware of the problem.&lt;/p&gt;

&lt;p&gt;Thankfully, &lt;a href="https://docs.sqlalchemy.org/en/13/core/events.html#sqlalchemy.events.ConnectionEvents.before_execute"&gt;SQLAlchemy’s events&lt;/a&gt; allow us to be notified when a query is about to be executed. We can create a listener that raises an exception when we try to run a problematic query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def before_execute(conn, clauseelement, multiparams, params):
    if (
        isinstance(clauseelement, sa.sql.selectable.Select)
        and len(clauseelement.froms) &amp;gt; 1
    ):
        raise RuntimeError("Cross join detected:\n{}".format(clauseelement))

sa.event.listen(engine, "before_execute", before_execute)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It’s not perfect because it does not check subqueries or CTEs but it gives us a line of defense. I am also thinking of adding an assertion that checks for the problem to the tests that exercise the query construction logic.&lt;/p&gt;

&lt;p&gt;Here is the complete example code: &lt;a href="///files/sqlalchemy_implicit_cross_join.py"&gt;sqlalchemy_implicit_cross_join.py&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>python</category>
      <category>sqlalchemy</category>
    </item>
    <item>
      <title>PostgreSQL: JSON aggregation</title>
      <dc:creator>Martin Vielsmaier</dc:creator>
      <pubDate>Fri, 16 Mar 2018 23:00:00 +0000</pubDate>
      <link>https://dev.to/moser/postgresql-json-aggregation-4k1o</link>
      <guid>https://dev.to/moser/postgresql-json-aggregation-4k1o</guid>
      <description>&lt;p&gt;On a client project I have to do a search in a structure of tables and return results including some child objects. A classical instance of the N+1 query problem, if I was using an ORM. I decided not to use the ORM for the feature because it will be one of the hottest paths of the application and I wanted more control over the queries (rather complex logic with &lt;code&gt;LIKE&lt;/code&gt; &amp;amp; sorting). But the filtering/sorting is not the topic today, so I will leave it out in the examples.&lt;/p&gt;

&lt;p&gt;For illustration, let’s assume the following schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;parents&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;parent_id&lt;/span&gt; &lt;span class="nb"&gt;INTEGER&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;children&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;child_id&lt;/span&gt; &lt;span class="nb"&gt;INTEGER&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;birthdate&lt;/span&gt; &lt;span class="nb"&gt;DATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;parent_id&lt;/span&gt; &lt;span class="nb"&gt;INTEGER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;FOREIGN&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parent_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;parents&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Without any further thinking I would do a query like this and a bit of code that constructs parent objects with their respective children.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;parents&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;children&lt;/span&gt; &lt;span class="k"&gt;USING&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parent_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;parent_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;parent_id | name | child_id | name | birthdate  
-----------+-------+----------+---------+------------
         1 | Jim | 1 | Tamara | 2017-02-01
         1 | Jim | 3 | Tom | 2005-10-01
         1 | Jim | 5 | Tonja | 2011-07-17
         2 | Jenny | 2 | Tim | 2000-11-02
         2 | Jenny | 4 | Theresa | 2017-04-30
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Just before I started writing the logic to pull apart the result and put it into it’s object structure, I thought, “It would be nice to let the database put together all the children of one parent into an array.”&lt;/p&gt;

&lt;p&gt;I already knew&lt;a href="https://www.postgresql.org/docs/9.6/static/functions-aggregate.html"&gt;&lt;code&gt;array_agg&lt;/code&gt;&lt;/a&gt;which aggregates all values into an array. After some reading I discovered&lt;a href="https://www.postgresql.org/docs/9.6/static/functions-json.html"&gt;&lt;code&gt;json_build_object&lt;/code&gt;&lt;/a&gt;which takes a sequence of keys and values and creates a JSON object from it.&lt;/p&gt;

&lt;p&gt;So my final query looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;parent_id&lt;/span&gt;
  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
  &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;array_agg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json_build_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="s1"&gt;'child_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;child_id&lt;/span&gt;
    &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
    &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'birthdate'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;birthdate&lt;/span&gt;
  &lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;children&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;parents&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;children&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt; &lt;span class="k"&gt;USING&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parent_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;parent_id | name | children                                                                                                              
-----------+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
         1 | Jim | {"{\"child_id\" : 1, \"name\" : \"Tamara\", \"birthdate\" : \"2017-02-01\"}","{\"child_id\" : 3, \"name\" : \"Tom\", \"birthdate\" : \"2005-10-01\"}","{\"child_id\" : 5, \"name\" : \"Tonja\", \"birthdate\" : \"2011-07-17\"}"}
         2 | Jenny | {"{\"child_id\" : 2, \"name\" : \"Tim\", \"birthdate\" : \"2000-11-02\"}","{\"child_id\" : 4, \"name\" : \"Theresa\", \"birthdate\" : \"2017-04-30\"}"}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;When the query is executed with sqlalchemy, &lt;code&gt;children&lt;/code&gt; in the resulting rows is already correctly typed as a list of dictionaries.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;explain analyze&lt;/code&gt; output for both queries (on a trivially small test set) shows that the aggregated version is 50-100% slower (150-200μs vs. 250-350μs), but I guess that will rarely be a real problem because - at least in my case&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the execution time of my query is dominated by filtering/sorting the parent rows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you would like to play with the example yourself, &lt;a href="https://moserei.de/files/postgresql-json.sql"&gt;get the SQL file here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>sql</category>
    </item>
    <item>
      <title>Python: bare except statement - why it is bad.</title>
      <dc:creator>Martin Vielsmaier</dc:creator>
      <pubDate>Tue, 19 Sep 2017 22:00:00 +0000</pubDate>
      <link>https://dev.to/moser/python-bare-except-statement-why-it-is-bad-17m2</link>
      <guid>https://dev.to/moser/python-bare-except-statement-why-it-is-bad-17m2</guid>
      <description>&lt;p&gt;The bare &lt;code&gt;except&lt;/code&gt; statement is something I often see in the main loop of a script that should run indefinitely. &lt;a href="http://pylint-messages.wikidot.com/messages:w0702"&gt;Pylint will warn&lt;/a&gt; you about this problem, but in my opinion we should start to treat this as an error.&lt;/p&gt;

&lt;p&gt;Consider the following code snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;time&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;risky_business&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;risky_business&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Problems?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exc_info&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This will work nicely to keep your program running whatever happends inside you&lt;code&gt;risky_business&lt;/code&gt; function. But let’s try to stop your program by pressing CTRL-C.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ python a.py 
^C('Problems?', (&amp;lt;type 'exceptions.KeyboardInterrupt'&amp;gt;, KeyboardInterrupt(), &amp;lt;traceback object at 0x7f234f6c9dd0&amp;gt;))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We caught the &lt;code&gt;KeyboardInterrupt&lt;/code&gt; exception and just carried on. But we catch more which we should not. Let’s try to exit the program from the business function, maybe because the user asked for it or we got signaled.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;risky_business&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ python a.py 
('Problems?', (&amp;lt;type 'exceptions.SystemExit'&amp;gt;, SystemExit(0,), &amp;lt;traceback object at 0x7f49b7ab5e18&amp;gt;))
('Problems?', (&amp;lt;type 'exceptions.SystemExit'&amp;gt;, SystemExit(0,), &amp;lt;traceback object at 0x7f49b7ab5ea8&amp;gt;))
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So why is this happening? Both &lt;code&gt;KeyboardInterrupt&lt;/code&gt; and &lt;code&gt;SystemExit&lt;/code&gt; are exceptions (derived from &lt;code&gt;BaseException&lt;/code&gt;). An &lt;code&gt;except&lt;/code&gt; statement without any restriction will catch any exception derived from &lt;code&gt;BaseException&lt;/code&gt;. &lt;a href="https://docs.python.org/3.5/library/exceptions.html#exception-hierarchy"&gt;Here is the complete hierachy of the builtin exceptions.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can fix our problem by restricting the kind of exception that we want to catch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;risky_business&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;risky_business&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Problems?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exc_info&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;When we press CTRL-C now, the program exits with the right exception.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ python a.py
^CTraceback (most recent call last):
  File "a.py", line 10, in &amp;lt;module&amp;gt;
    risky_business()
  File "a.py", line 6, in risky_business
    time.sleep(1)
KeyboardInterrupt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Pylint will still &lt;a href="http://pylint-messages.wikidot.com/messages:w0703"&gt;warn&lt;/a&gt; you about this line, because catching &lt;code&gt;Exception&lt;/code&gt; is still very broad and you should only do this when you have a good reason, e.g. the reason mentioned above (to keep a service running even if it could not handle a certain input or request).&lt;/p&gt;

&lt;p&gt;So next time you see a bare &lt;code&gt;except&lt;/code&gt; statement in your code, take a moment to reconsider if you really want to catch &lt;code&gt;SystemExit&lt;/code&gt;, &lt;code&gt;KeyboardInterrupt&lt;/code&gt; (and&lt;code&gt;GeneratorExit&lt;/code&gt; which I did not mention above). If that is the case, you might want to make it explicit so that the next person reading the code does not have to check again.&lt;/p&gt;

</description>
      <category>python</category>
    </item>
  </channel>
</rss>
